go配置管理vpier

go配置管理viper

Viper 提供了丰富的 API 来处理配置管理的各种场景,下面详细讲解其常用 API 及核心功能:

安装

1
go get github.com/spf13/viper

简介

Viper,直译为眼镜蛇,是一个针对 go 应用程序的完整的配置文件解决方案,可以处理几乎所有类型的配置需求和格式,方便管理项目的配置文件,并且具有以下特色:

  • 默认值设置
  • 支持格式 JSON, TOML, YAML, HCL, envfile,Java properties
  • 支持实时监测和重载配置文件
  • 支持环境变量中读取
  • 支持远程配置系统读取配置并监测变化
  • 支持读取命令行标记
  • 支持缓冲区读取
  • 支持显示设置值

一、常用 API 及功能详解

1. 配置读取相关 API

  • Get(key string) interface{}:获取任意类型的配置值
  • GetString(key string) string:获取字符串类型
  • GetInt(key string) int:获取整数类型
  • GetBool(key string) bool:获取布尔类型
  • GetFloat64(key string) float64:获取浮点类型
  • GetStringSlice(key string) []string:获取字符串切片
  • GetIntSlice(key string) []int:获取整数切片
  • GetStringMap(key string) map[string]interface{}:获取嵌套的 map
  • IsSet(key string) bool:检查配置项是否存在

示例:

1
2
3
4
name := viper.GetString("app.name")
port := viper.GetInt("server.port")
isDebug := viper.GetBool("app.debug")
tags := viper.GetStringSlice("app.tags")

2. 配置设置相关 API

  • Set(key string, value interface{}):设置配置值(内存中)
  • SetDefault(key string, value interface{}):设置默认值(未找到配置时使用)

示例:

1
2
3
4
5
6
// 设置默认值
viper.SetDefault("server.port", 8080)
viper.SetDefault("log.level", "info")

// 动态设置配置
viper.Set("cache.enabled", true)

3. 配置文件操作 API

  • 读取配置文件

    • SetConfigName(name string):设置配置文件名(不带扩展名)
    • SetConfigType(ext string):设置配置文件类型(如 “yaml”、”json”)
    • AddConfigPath(path string):添加配置文件搜索路径
    • ReadInConfig() error:加载配置文件

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    viper.SetConfigName("app")       // 配置文件名为 app.yaml
    viper.SetConfigType("yaml")
    viper.AddConfigPath(".") // 当前目录
    viper.AddConfigPath("/etc/app") // 系统目录

    if err := viper.ReadInConfig(); err != nil {
    log.Fatalf("无法读取配置文件: %v", err)
    }
  • 写入配置文件

    • WriteConfig() error:写入当前配置到配置文件(覆盖原有内容)
    • SafeWriteConfig() error:仅当文件不存在时写入(避免覆盖)
    • WriteConfigAs(filename string) error:写入配置到指定文件

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 修改配置
    viper.Set("server.port", 9090)

    // 写入到原有配置文件
    if err := viper.WriteConfig(); err != nil {
    log.Fatal(err)
    }

    // 写入到新文件
    if err := viper.WriteConfigAs("app_backup.yaml"); err != nil {
    log.Fatal(err)
    }

4. 环境变量与命令行相关 API

  • AutomaticEnv():自动绑定环境变量
  • SetEnvPrefix(prefix string):设置环境变量前缀
  • SetEnvKeyReplacer(replacer *strings.Replacer):替换环境变量中的分隔符
  • BindEnv(input ...string):手动绑定环境变量到配置项
  • BindPFlags(flags *pflag.FlagSet):绑定命令行参数

示例:

1
2
3
4
5
6
7
8
9
// 环境变量前缀为 "MYAPP",自动绑定
viper.SetEnvPrefix("myapp")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) // 将 . 转为 _
viper.AutomaticEnv()

// 绑定命令行参数
pflag.Int("port", 8080, "服务器端口")
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)

5. 配置监测与重载 API

  • WatchConfig():监听配置文件变化
  • OnConfigChange(func(e fsnotify.Event)):注册配置变化回调函数

示例:

1
2
3
4
5
6
7
8
// 监听配置文件
viper.WatchConfig()

// 配置变化时触发
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Printf("配置文件 %s 已修改\n", e.Name)
// 可在这里重新加载配置或执行自定义逻辑
})

6. 别名与嵌套分隔符 API

  • RegisterAlias(alias, key string):为配置项注册别名
  • SetKeyDelimiter(delimiter string):设置嵌套配置的分隔符(默认是 .

示例:

1
2
3
4
5
6
// 注册别名:通过 "addr" 也能访问 "server.address"
viper.RegisterAlias("addr", "server.address")

// 修改嵌套分隔符为 "/"(默认是 ".")
viper.SetKeyDelimiter("/")
port := viper.GetInt("server/port") // 等价于原来的 "server.port"

7. 子结构提取 API

  • Sub(key string) *viper.Viper:提取子配置结构,返回一个新的 Viper 实例

示例:

1
2
3
4
5
6
7
8
# 配置文件内容
database:
mysql:
host: localhost
port: 3306
postgres:
host: 127.0.0.1
port: 5432
1
2
3
4
5
6
// 提取 database.mysql 子结构
mysqlConfig := viper.Sub("database.mysql")
if mysqlConfig != nil {
fmt.Println(mysqlConfig.GetString("host")) // 输出 localhost
fmt.Println(mysqlConfig.GetInt("port")) // 输出 3306
}

8. 序列化与反序列化 API

  • Unmarshal(rawVal interface{}) error:将配置反序列化为结构体
  • UnmarshalKey(key string, rawVal interface{}) error:将指定 key 的配置反序列化为结构体
  • AllSettings() map[string]interface{}:获取所有配置并序列化为 map

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 定义结构体
type ServerConfig struct {
Port int `mapstructure:"port"`
Host string `mapstructure:"host"`
}

type AppConfig struct {
Name string `mapstructure:"name"`
Server ServerConfig `mapstructure:"server"`
}

// 反序列化所有配置
var appCfg AppConfig
if err := viper.Unmarshal(&appCfg); err != nil {
log.Fatal(err)
}

// 反序列化子配置
var serverCfg ServerConfig
if err := viper.UnmarshalKey("server", &serverCfg); err != nil {
log.Fatal(err)
}

// 序列化为 map
allConfig := viper.AllSettings()

二、配置读取顺序(优先级从高到低)

Viper 支持多来源配置,读取顺序如下:

  1. 手动调用 Set() 方法设置的值
  2. 命令行参数(通过 BindPFlags 绑定)
  3. 环境变量
  4. 配置文件
  5. 远程配置(如 etcd)
  6. 调用 SetDefault() 设置的默认值

三、核心功能总结

功能 关键 API
读取配置文件 ReadInConfig()AddConfigPath()
写入配置文件 WriteConfig()WriteConfigAs()
环境变量处理 AutomaticEnv()SetEnvPrefix()
配置监测重载 WatchConfig()OnConfigChange()
别名与分隔符 RegisterAlias()SetKeyDelimiter()
子结构提取 Sub()
序列化 / 反序列化 Unmarshal()AllSettings()
[up主专用,视频内嵌代码贴在这]