Go 学习笔记(82)— Go 第三方库之 viper(解析配置文件、热更新配置文件)
1. viper 特点
viper
是一个完整的 Go
应用程序的配置解决方案,它被设计为在应用程序中工作,并能处理所有类型的配置需求和格式。支持特性功能如下:
- 设置默认值
- 读取
JSON
、TOML
、YAML
、HCL
、envfile
和Java
属性的配置文件 - 监控配置文件改动,并热加载配置文件
- 从环境变量中读取
- 从远程配置中心读取配置(etcd/consul),并监控变动
- 从命令行标志中读取
- 从缓冲区读取
- 支持直接设置配置项的值
viper
读取配置文件的优先级顺序:
viper.Set()
所设置的值- 命令行
flag
- 环境变量
- 配置文件
- 配置中心
etcd/consul
- 默认值
注意:
viper
的配置键是不区分大小写的。
2. 安装
官网地址:https://github.com/spf13/viper 安装命令
go get github.com/spf13/viper
3. 将配置注册到 viper
3.1 创建默认值
viper.SetDefault("Name", "wohu")
viper.SetDefault("Gender", "male")
viper.SetDefault("City", map[string]string{"country": "China", "Province": "Beijing"})
3.2 从配置文件读取值
viper
默认不配置文件的搜索路径,将配置文件路径的搜索决定权放在用户程序中。
viper.SetConfigName("config") // 配置文件名字,注意没有扩展名
viper.SetConfigType("yaml") // 如果配置文件的名称中没有包含扩展名,那么该字段是必需的
viper.AddConfigPath("/etc/appname/") // 配置文件的路径
viper.AddConfigPath("$HOME/.appname") // 多次调用添加多个配置文件的路径
viper.AddConfigPath(".") // 在当前工作目录寻找配置文件
err := viper.ReadInConfig() // 查找并读取配置文件
if err != nil { panic(fmt.Errorf("Fatal error config file: %w \n", err))
}
3.3 将 viper值保存到配置文件
viper.WriteConfig()
将当前的配置写到预先通过 viper.AddConfigPath()
和 viper.SetConfigName()
配置的路径,如果该目录下已经有对应的配置文件则会覆盖,如果找不到对应的路径则报错。
viper.SafeWriteConfig() // 与第一个区别是不会覆盖当前已经存在的文件
viper.WriteConfigAs("/path/to/my/.config") // 会覆盖当前已经存在的文件
viper.SafeWriteConfigAs("/path/to/my/.config") // 不会覆盖当前已经存在的文件
viper.SafeWriteConfigAs("/path/to/my/.other_config")
3.4 监测并热加载配置文件
viper
支持应用程序在运行中实时读取配置文件的能力。确保在调用 WatchConfig()
之前添加所有的configPaths
。
viper.OnConfigChange(func(e fsnotify.Event) {fmt.Println("Config file changed:", e.Name)
})
viper.WatchConfig()
3.5 从 io.Reader 读取配置
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")// any approach to require this configuration into your program.
var yamlExample = []byte(`
Hacker: true
name: steve
hobbies:
- skateboarding
- snowboarding
- go
clothing:jacket: leathertrousers: denim
age: 35
eyes : brown
beard: true
`)viper.ReadConfig(bytes.NewBuffer(yamlExample))viper.Get("name") // this would be "steve"
4. 从 viper 读取配置
4.1 读取单个值方法
在 viper
中,有几种方法来获取一个值,这取决于该值的类型。存在以下函数和方法。
Get(key string) : interface{}
GetBool(key string) : bool
GetFloat64(key string) : float64
GetInt(key string) : int
GetIntSlice(key string) : []int
GetString(key string) : string
GetStringMap(key string) : map[string]interface{}
GetStringMapString(key string) : map[string]string
GetStringSlice(key string) : []string
GetTime(key string) : time.Time
GetDuration(key string) : time.Duration
IsSet(key string) : bool
AllSettings() : map[string]interface{}
注意:如果没有找到,每个
Get
函数将返回一个0
值。为了检查一个给定的键是否存在,已经提供了IsSet()
方法。
4.1 读取嵌套的配置
{"host": {"address": "localhost","port": 5799},"datastore": {"metric": {"host": "127.0.0.1","port": 3099},"warehouse": {"host": "198.0.0.1","port": 2112}}
}
viper
可以通过传递一个以 .
为界的键值路径来访问一个嵌套字段。
GetString("datastore.metric.host") // (returns "127.0.0.1")
viper
可以通过使用路径中的数字来访问数组索引,例如
{"host": {"address": "localhost","ports": [5799,6029]},"datastore": {"metric": {"host": "127.0.0.1","port": 3099},"warehouse": {"host": "198.0.0.1","port": 2112}}
}GetInt("host.ports.1") // returns 6029
如果存在一个与划定的键路径相匹配的键,其值将被返回。例如。
{"datastore.metric.host": "0.0.0.0","host": {"address": "localhost","port": 5799},"datastore": {"metric": {"host": "127.0.0.1","port": 3099},"warehouse": {"host": "198.0.0.1","port": 2112}}
}GetString("datastore.metric.host") // returns "0.0.0.0"
5. 使用示例
代码结构如下:
.
├── conf
│ └── config.yaml
├── config
│ └── config.go
├── go.mod
├── go.sum
├── main.go
└── README.md2 directories, 6 files
config.yaml
内容
name: demo
host: 127.0.0.1:3306
username: root
password: root
config.go
内容:
package configimport ("log""github.com/fsnotify/fsnotify""github.com/spf13/viper"
)type Config struct {Name stringHost stringUsername stringPassword string
}func Init() (*Config, error) {viper.AddConfigPath("conf") // 设置配置文件路径viper.SetConfigName("config") // 设置配置文件名viper.SetConfigType("yaml") // 设置配置文件类型格式为YAML// 初始化配置文件if err := viper.ReadInConfig(); err != nil { // viper解析配置文件return &Config{}, err}// 监控配置文件变化并热加载程序,即不重启程序进程就可以加载最新的配置viper.WatchConfig()viper.OnConfigChange(func(e fsnotify.Event) {log.Printf("Config file changed: %s", e.Name)})c := &Config{Name: viper.GetString("name"),Host: viper.GetString("host"),Username: viper.GetString("username"),Password: viper.GetString("password"),}return c, nil
}
main.go
内容:
package mainimport ("fmt""time""webserver/config""github.com/spf13/viper"
)func main() {// init config_, err := config.Init()if err != nil {fmt.Println(err)}// 注意:只能在 init 之后再次通过 viper.Get 方法读取配置,否则不生效for {cfg := &config.Config{Name: viper.GetString("name"),Host: viper.GetString("host"),Username: viper.GetString("username"),Password: viper.GetString("password"),}fmt.Println(cfg.Name)time.Sleep(4 * time.Second)}}
运行 main.go
之后修改配置文件查看打印:
$ go run main.go
123
123
2021/12/03 14:05:45 Config file changed: /home/wohu/goProject/webserver/conf/config.yaml
2021/12/03 14:05:45 Config file changed: /home/wohu/goProject/webserver/conf/config.yaml
345
345
345
2021/12/03 14:05:56 Config file changed: /home/wohu/goProject/webserver/conf/config.yaml
2021/12/03 14:05:56 Config file changed: /home/wohu/goProject/webserver/conf/config.yaml
demo
demo
Go 学习笔记(82)— Go 第三方库之 viper(解析配置文件、热更新配置文件)相关推荐
- python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件? 当我们点开下载页时, 一 ...
- python3第三方库手册_python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑...
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件? 当我们点开下载页时, 一 ...
- python学习笔记项目_python第三方库之Django学习笔记一
1.安装Django pip install Django 2.版本号查询 python -m django --version 3.创建项目 切换到你想创建项目的目录,执行命令:django-adm ...
- STM32CUBEMX入门学习笔记3:HAL库以及STM32CUBE相关资料
STM32CUBEMX入门学习笔记3:HAL库以及STM32CUBE相关资料 微雪课堂:http://www.waveshare.net/study/article-629-1.html 之前的正点原 ...
- Makefile学习笔记07|编译静态库并通过ifeq语句
Makefile学习笔记07|编译静态库并通过ifeq语句 希望看到这篇文章的朋友能在评论区留下宝贵的建议来让我们共同成长,谢谢. 这里是目录 本篇与上一篇有较多联系,有兴趣的可以先看上一 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- js学习笔记82——操作内联样式
js学习笔记82--操作内联样式 通过js修改元素的样式 查参考手册 内联样式 读取元素的样式 看如下代码 <!DOCTYPE html> <html lang="en&q ...
- Python学习笔记:列表、字典与集合解析(List, Dict and Set Comprehensions)
Python学习笔记:列表.字典与集合解析(List, Dict and Set Comprehensions) 1.列表解析 最受喜爱的Python语言特性.过滤一个集合的元素生成一个新的列表. 一 ...
- Python学习笔记:常用第三方模块3
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- Python学习笔记:常用第三方模块(1)
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
最新文章
- linux samba免密码,Ubuntu如何不用密码访问samba服务器
- qt-designer使用教程3--编写自己的槽
- java 反射field_Java基础--反射之Field
- ssh 免密_Linux下配置SSH免密通信 “sshkeygen”的基本用法
- 图形裁剪算法matlab,MATLAB裁剪图片
- mysql 按时间分库分表_sharding-jdbc 按时间分库分表
- FluentAPI --- 用C#写的JS代码生成器
- 2022年新版YOLO解读(PP-YOLOE)
- Java中,类的实例化方法
- xps数据怎么导出为txt_如何处理XPS原始数据
- 微信测试账户申请以及测试
- (软考)图示法求候选键,及快捷求候选键,和数据库模式分解的表格法,及无损连接分解的快捷判别方法
- 网络通过mac定位机器_如何设置Mac以充当网络时间机器驱动器
- BIM土建插件墙齐梁板操作,实现墙、柱的顶部、底部对齐
- C#将数据导入固定word模板
- 存储过程中 IN,OUT,INOUT类型参数的区别
- C语言 memcpy和memcpy_s
- 从新手运气到幸存者偏差
- MindMapper使用技巧分享
- 嵌入式系统设计与开发期末考试复习