Skip to content

多环境配置 ​

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: 10

config-dev.yaml ​

yaml
app:
  port: 8080
  debug: true

database:
  host: localhost
  port: 3306
  user: root
  password: root

config-prod.yaml ​

yaml
app:
  port: 80
  debug: false

database:
  host: prod-db.internal
  port: 3306
  user: appuser
  password: ${DB_PASSWORD}

参考:https://github.com/spf13/viper