golang常用库之-配置文件解析 spf13/viper包 | 解析加载配置
文章目录
- golang常用库之-配置文件解析 spf13/viper包 | 解析&加载配置
- 一、背景
- 二、什么是viper
- 三、为什么选择Viper?🚀
- 四、viper基础
- 四、使用demo
- 1. 利用viper写toml格式的文件
- 2. 利用viper读取配置文件
- 3. 监听配置变化
- 4. 设置默认值
- 5. 【重要】 使用标志
- 6. 【重要】反序列化
- 参考
golang常用库之-配置文件解析 spf13/viper包 | 解析&加载配置
一、背景
在我们开发过程中,像数据库信息、邮件配置和其他的第三方服务密钥等这些固定的信息都会写在配置文件中,而配置文件又有多种表现形式和格式,有 JSON, TOML, YAML各种格式,而且测试环境,开发环境和生产环境用的配置文件也不是同一份。
我们需要一个go 库可以做这件事!
二、什么是viper
github: https://github.com/spf13/viper
viper
美: [ˈvaɪpər]
英: [ˈvaɪpə®]
n. 蝰蛇(一种小毒蛇);毒如蛇蝎的人;险恶的人
网络 冥界亚龙;道奇蝰蛇;蝮蛇
Viper是Go应用程序的完整配置解决方案,
viper 支持Yaml、Json、 TOML、HCL 等格式,读取非常的方便。
- 设置默认值
- 从JSON、TOML、YAML、HCL、envfile和Java properties格式的配置
- 文件读取配置信息
- 实时监控和重新读取配置文件(可选)
- 从环境变量中读取
- 从远程配置系统(etcd或Consul)读取并监控配置变化
- 从命令行参数读取配置
- 从buffer读取配置
- 调用函数设置配置信息
Viper can be thought of as a registry for all of your applications configuration needs.
Viper可以被认为是您的所有应用程序配置需求的注册表
三、为什么选择Viper?🚀
Viper
参考URL: https://www.cnblogs.com/zc110/articles/14603870.html
在构建现代应用程序时,你无需担心配置文件格式;你想要专注于构建出色的软件。Viper的出现就是为了在这方面帮助你的。
Viper能够为你执行下列操作:
- 查找、加载和反序列化JSON、TOML、YAML、HCL、INI、envfile和Java properties格式的配置文件。
- 提供一种机制为你的不同配置选项设置默认值。
- 提供一种机制来通过命令行参数覆盖指定选项的值。
- 提供别名系统,以便在不破坏现有代码的情况下轻松重命名参数。
- 当用户提供了与默认值相同的命令行或配置文件时,可以很容易地分辨出它们之间的区别。
Viper会按照下面的优先级。每个项目的优先级都高于它下面的项目:
- 显示调用Set设置值
- 命令行参数(flag)
- 环境变量
- 配置文件
- key/value存储
- 默认值
四、viper基础
Viper 可以从不同的位置读取配置,不同位置的配置具有不同的优先级,高优先级的配置会覆盖低优先级相同的配置,按优先级从高到低排列如下:
- 通过 viper.Set 函数显示设置的配置
- 命令行参数
- 环境变量
- 配置文件
- Key/Value 存储
- 默认值
四、使用demo
1. 利用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的文件
相对于写入配置文件的操作。
2. 利用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)
3. 监听配置变化
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("配置发生变更:", e.Name)
})
不建议在实际开发中使用热加载功能,因为即使配置热加载了,程序中的代码也不一定会热加载。例如:修改了服务监听端口,但是服务没有重启,这时候服务还是监听在老的端口上,会造成不一致。
4. 设置默认值
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
5. 【重要】 使用标志
Viper 支持 Pflag 包,能够绑定 key 到 Flag。我们可以将标志绑定到 Viper,这样就可以使用 viper.Get() 获取标志的值。
绑定单个标志
viper.BindPFlag("token", pflag.Lookup("token"))
还可以绑定一组现有的 pflags(pflag.FlagSet):
viper.BindPFlags(pflag.CommandLine)
注意:工作中,这个常用到,一般都是命令行优先与配置文件,这样配置统一就是viper来管理,最后一次反序列化到我们的配置实例中。
6. 【重要】反序列化
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实例,方便代码使用。
参考
Viper
参考URL: https://www.cnblogs.com/zc110/articles/14603870.html