背景
在我们开发过程中,像数据库信息、邮件配置和其他的第三方服务密钥等这些固定的信息都会写在配置文件中,而配置文件又有多种表现形式和格式,有 JSON, TOML, YAML各种格式,而且测试环境,开发环境和生产环境用的配置文件也不是同一份。
什么是Viper?
Viper是Go应用程序的完整配置解决方案, viper 支持Yaml、Json、 TOML、HCL 等格式,读取非常的方便。
- 设置默认值
- 从JSON、TOML、YAML、HCL、envfile和Java properties格式的配置
- 文件读取配置信息
- 实时监控和重新读取配置文件(可选)
- 从环境变量中读取
- 从远程配置系统(etcd或Consul)读取并监控配置变化
- 从命令行参数读取配置
- 从buffer读取配置
- 调用函数设置配置信息
Viper主要为我们做以下工作:
- 查找、加载和解组JSON、TOML、YAML、HCL、INI、envfile或Java属性格式的配置文件。
- 提供一种机制来为不同的配置选项设置默认值。
- 提供一种机制来为通过命令行标志指定的选项设置覆盖值。
- 提供别名系统,以便在不破坏现有代码的情况下轻松重命名参数。
- 当用户提供了与默认值相同的命令行或配置文件时,很容易区分它们。
viepr的安装很简单,直接再工程中使用go get命令安装即可
go get github.com/spf13/viper
使用demo
利用viper写toml格式的文件
func init(){
viper.SetConfigFile("hello.toml")//文件名
viper.Set("Address","0.0.0.0:9090")//统一把Key处理成小写 Address->address
err := viper.WriteConfig()//写入文件
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
}
运行一下,会发现当前目录会出现一个hello.toml的文件。相对于写入配置文件的操作。
利用viper读取配置文件
viper.SetConfigFile("hello.toml")
err := viper.ReadInConfig() // 会查找和读取配置文件
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
Address = viper.GetString("Address")
//key取Address或者address都能取到值,反正viper转成小写处理
fmt.Println(Address)
监听配置变化
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("配置发生变更:", e.Name)
})
不建议在实际开发中使用热加载功能,因为即使配置热加载了,程序中的代码也不一定会热加载。例如:修改了服务监听端口,但是服务没有重启,这时候服务还是监听在老的端口上,会造成不一致。
设置默认值
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
【重要】反序列化
Viper 可以支持将所有或特定的值解析到结构体、map 等。可以通过两个函数来实现:
Unmarshal(rawVal interface{}) error
UnmarshalKey(key string, rawVal interface{}) error
type config struct {
Port int
Name string
PathMap string `mapstructure:"path_map"`
}
var C config
err := viper.Unmarshal(\&C)
if err != nil {
t.Fatalf("unable to decode into struct, %v", err)
}
Viper 在后台使用 github.com/mitchellh/mapstructure 来解析值,其默认情况下使用mapstructure tags。当我们需要将 Viper 读取的配置反序列到我们定义的结构体变量中时,一定要使用 mapstructure tags。
注意:工作中,这个常用到,这块就是把我们从配置文件中读到内容,反序列化特定的struct实例,方便代码使用。
配置加载顺序
- 设置显示调用(explicit call to Set)
- 命令行标志(flag)
- 环境变量(env)
- 配置文件(config)
- 远程键/值存储(key/value store)
- 默认值(default)
总结
Viper是一个非常有用的开源库,用于读取和处理应用程序的配置,能够大大减轻我们的工作量。在本文中,我们介绍了如何安装和使用Viper,希望对您有所帮助。如果您需要更多信息,请查看Viper的官方文档。
参考
golang如何安装和使用Viper: www.php.cn/faq/507959.…