Go配置管理与环境变量
Go配置管理结合环境变量和配置文件,实现灵活的应用配置。
环境变量操作
os.Getenv读取
Go
import "os"
// 读取环境变量
path := os.Getenv("PATH")
// 不存在返回空字符串
val := os.Getenv("NOT_EXIST") // ""
// 无法区分不存在和空值
os.LookupEnv安全读取
Go
// 区分不存在和空值
val, exists := os.LookupEnv("MY_VAR")
if !exists {
fmt.Println("环境变量不存在")
} else if val == "" {
fmt.Println("环境变量为空")
} else {
fmt.Println("值:", val)
}
推荐使用LookupEnv区分不存在和空值。
设置和删除
Go
// 设置环境变量(仅当前进程)
os.Setenv("MY_VAR", "my_value")
// 删除环境变量
os.Unsetenv("MY_VAR")
// 清除所有环境变量
os.Clearenv()
// 获取所有环境变量
envs := os.Environ() // 返回 []string
配置读取最佳实践
带默认值读取
Go
func getEnvOrDefault(key, defaultVal string) string {
if val, exists := os.LookupEnv(key); exists && val != "" {
return val
}
return defaultVal
}
// 使用
port := getEnvOrDefault("PORT", "8080")
dbURL := getEnvOrDefault("DATABASE_URL", "localhost:5432")
debug := getEnvOrDefault("DEBUG", "false") == "true"
配置结构体
Go
type Config struct {
Port string
DatabaseURL string
Debug bool
APIKey string
}
func LoadConfig() *Config {
return &Config{
Port: getEnvOrDefault("PORT", "8080"),
DatabaseURL: getEnvOrDefault("DATABASE_URL", ""),
Debug: os.Getenv("DEBUG") == "true",
APIKey: os.Getenv("API_KEY"),
}
}
// 使用
config := LoadConfig()
runServer(config.Port)
配置文件管理
JSON配置
Go
type Config struct {
Port int `json:"port"`
Host string `json:"host"`
}
func LoadJSONConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var config Config
err = json.Unmarshal(data, &config)
return &config, err
}
YAML配置
Go
import "gopkg.in/yaml.v3"
type Config struct {
Port int `yaml:"port"`
Host string `yaml:"host"`
}
func LoadYAMLConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var config Config
err = yaml.Unmarshal(data, &config)
return &config, err
}
配置优先级
多层配置覆盖
Go
func LoadConfig() *Config {
// 1. 默认值
config := &Config{
Port: "8080",
}
// 2. 配置文件覆盖
if fileConfig, err := loadFileConfig(); err == nil {
mergeConfig(config, fileConfig)
}
// 3. 环境变量覆盖(最高优先级)
if port := os.Getenv("PORT"); port != "" {
config.Port = port
}
return config
}
优先级规则
Go
环境变量 > 配置文件 > 默认值
// 原因:
// 环境变量可动态修改
// 配置文件相对固定
// 默认值作为兜底
敏感信息处理
不硬编码敏感信息
Go
// ✗ 错误:硬编码密码
password := "secret123"
// ✓ 正确:从环境变量读取
password := os.Getenv("DB_PASSWORD")
if password == "" {
log.Fatal("DB_PASSWORD not set")
}
检查必需配置
Go
func validateConfig(config *Config) error {
if config.APIKey == "" {
return errors.New("API_KEY required")
}
if config.DatabaseURL == "" {
return errors.New("DATABASE_URL required")
}
return nil
}
config := LoadConfig()
if err := validateConfig(config); err != nil {
log.Fatal(err)
}
os包环境变量函数表
| 函数 | 用途 | 返回值 |
|---|---|---|
| Getenv | 读取变量 | string |
| LookupEnv | 安全读取 | string, bool |
| Setenv | 设置变量 | error |
| Unsetenv | 删除变量 | error |
| Clearenv | 清除所有 | 无 |
| Environ | 获取全部 | []string |
配置管理示例
text
type ServerConfig struct {
Port string
Host string
ReadTimeout int
Debug bool
}
func NewServerConfig() *ServerConfig {
return &ServerConfig{
Port: getEnvOrDefault("SERVER_PORT", "8080"),
Host: getEnvOrDefault("SERVER_HOST", "localhost"),
ReadTimeout: parseEnvInt("READ_TIMEOUT", 30),
Debug: os.Getenv("DEBUG") == "true",
}
}
func parseEnvInt(key string, defaultVal int) int {
if val := os.Getenv(key); val != "" {
n, err := strconv.Atoi(val)
if err == nil {
return n
}
}
return defaultVal
}
要点总结
- os.Getenv读取变量,不存在返回空字符串
- os.LookupEnv可区分不存在和空值
- 推荐使用LookupEnv安全读取
- 环境变量优先级高于配置文件
- 敏感信息必须从环境变量读取
- 配置结构体集中管理配置项
- 配置文件用JSON/YAML格式
- 检查必需配置防止运行时错误
- Setenv/Unsetenv仅影响当前进程
📝 发现内容有误?点击此处直接编辑