最佳实践
使用 Viper 进行配置管理的最佳实践。
配置结构设计
推荐配置结构
go
type Config struct {
App AppConfig `mapstructure:"app"`
Server ServerConfig `mapstructure:"server"`
Database DatabaseConfig `mapstructure:"database"`
Redis RedisConfig `mapstructure:"redis"`
Log LogConfig `mapstructure:"log"`
}
type AppConfig struct {
Name string `mapstructure:"name"`
Version string `mapstructure:"version"`
Env string `mapstructure:"env"`
}
type ServerConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
ReadTimeout time.Duration `mapstructure:"read_timeout"`
WriteTimeout time.Duration `mapstructure:"write_timeout"`
}
type DatabaseConfig struct {
Driver string `mapstructure:"driver"`
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Name string `mapstructure:"name"`
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
MaxOpenConns int `mapstructure:"max_open_conns"`
MaxIdleConns int `mapstructure:"max_idle_conns"`
ConnMaxLifetime int `mapstructure:"conn_max_lifetime"`
}配置加载流程
标准加载流程
go
func LoadConfig(configPath string) (*Config, error) {
v := viper.New()
// 1. 设置默认值
setDefaults(v)
// 2. 读取配置文件
v.SetConfigFile(configPath)
if err := v.ReadInConfig(); err != nil {
return nil, err
}
// 3. 读取环境变量
v.AutomaticEnv()
v.SetEnvPrefix("APP")
// 4. 解析配置
var config Config
if err := v.Unmarshal(&config); err != nil {
return nil, err
}
// 5. 验证配置
if err := validateConfig(&config); err != nil {
return nil, err
}
return &config, nil
}最佳实践总结
- 结构化配置:使用结构体定义配置
- 设置默认值:为关键配置设置合理默认值
- 多源组合:配置文件 + 环境变量 + 命令行
- 配置验证:加载后验证配置有效性
- 敏感信息:使用环境变量存储敏感信息
- 配置文档:维护配置文档说明
- 版本控制:配置文件纳入版本控制