多环境配置
Viper 支持多种多环境配置管理策略。
环境变量区分
使用环境变量指定环境
go
package main
import (
"fmt"
"os"
"github.com/spf13/viper"
)
func main() {
env := os.Getenv("APP_ENV")
if env == "" {
env = "dev"
}
viper.SetConfigName(fmt.Sprintf("config-%s", env))
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
panic(err)
}
fmt.Println(viper.GetString("app.name"))
}配置文件示例
yaml
# config-dev.yaml
app:
name: myapp-dev
port: 8080
database:
host: localhost
port: 3306
# config-prod.yaml
app:
name: myapp-prod
port: 80
database:
host: prod-db
port: 3306配置合并策略
基础配置 + 环境配置
go
func LoadConfig(env string) error {
viper.SetConfigType("yaml")
viper.SetConfigName("config-base")
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
return err
}
viper.SetConfigName(fmt.Sprintf("config-%s", env))
if err := viper.MergeInConfig(); err != nil {
return err
}
return nil
}配置优先级
1. 环境变量 (最高)
2. 环境配置文件 (config-{env}.yaml)
3. 基础配置文件 (config-base.yaml)
4. 默认值 (最低)环境变量覆盖
使用环境变量覆盖配置
go
viper.SetEnvPrefix("APP")
viper.AutomaticEnv()
// APP_DATABASE_HOST 覆盖 database.host
viper.BindEnv("database.host", "APP_DATABASE_HOST")完整示例
go
package main
import (
"github.com/spf13/viper"
)
type Config struct {
App struct {
Name string `mapstructure:"name"`
Port int `mapstructure:"port"`
} `mapstructure:"app"`
Database struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
} `mapstructure:"database"`
}
func LoadConfig() (*Config, error) {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.SetDefault("app.port", 8080)
viper.SetDefault("database.port", 3306)
if err := viper.ReadInConfig(); err != nil {
return nil, err
}
viper.SetEnvPrefix("APP")
viper.AutomaticEnv()
var config Config
if err := viper.Unmarshal(&config); err != nil {
return nil, err
}
return &config, nil
}多环境配置示例
config.yaml (基础配置)
yaml
app:
name: myapp
version: 1.0.0
database:
driver: mysql
name: mydb
max_open_conns: 100
max_idle_conns: 10config-dev.yaml
yaml
app:
port: 8080
debug: true
database:
host: localhost
port: 3306
user: root
password: rootconfig-prod.yaml
yaml
app:
port: 80
debug: false
database:
host: prod-db.internal
port: 3306
user: appuser
password: ${DB_PASSWORD}