项目中经常获取一些常用配置文件,当有配置文件中的参数被修改后,如何的实时获取配置文件就很关键了。这里推荐 ”viper” 这个包,用来实时获取配置文件。
1.VIPER 简介
viper【蝰蛇】
Viper 是适用于 Go 应用程序的完整配置解决方案。它旨在在应用程序中工作,并且可以处理所有类型的配置需求和格式。它支持:
- 设置默认值
- 从 JSON,TOML,YAML,HCL,envfile 和 Java 属性配置文件中读取
- 实时观看和重新读取配置文件(可选)
- 从环境变量中读取
- 从远程配置系统(etcd 或 Consul)中读取,并观察更改
- 从命令行标志读取
- 从缓冲区读取
- 设置显式值
可以将 Viper 视为满足您所有应用程序配置需求的注册表。
2. 使用说明
本文中的实例都是从 viper 的官方介绍中复制过来,只是介绍了简单的使用。完整的实例请查看【https://pkg.go.dev/github.com…】
2.1 建立默认值
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
2.2 读取配置文件
viper.SetConfigName("config") // name of config file (without extension)
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
viper.AddConfigPath("/etc/appname/") // path to look for the config file in
viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths
viper.AddConfigPath(".") // optionally look for config in the working directory
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
2.3 读取和重新读取配置文件
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {fmt.Println("Config file changed:", e.Name)
})
2.4 获取值
在 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{}
3. 实例代码
使用 GIN 框架,简单配置一个可以通过接口获取配置内容的 http 服务。当调用接口 http://127.0.0.1:8080/getConfig 可以获取配置项
步骤 1:设置配置文件
在工作目录中创建 config.yml 文件,文件内容如下:
Version: "2.1"
Debug: false
MongoDB:
IP: 127.0.0.1
Port: 27017
DbName: "db_name"
步骤二:编写服务代码
package main
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
)
var config *viper.Viper
func main() {config = initConfigure()
r := gin.Default()
r.GET("/getConfig", func(c *gin.Context) {
c.JSON(200, gin.H{"config": config.AllSettings(),
})
})
r.Run() // listen and serve on 0.0.0.0:8080}
func initConfigure() *viper.Viper {v := viper.New()
v.SetConfigName("config") // 设置文件名称(无后缀)v.SetConfigType("yaml") // 设置后缀名 {"1.6 以后的版本可以不设置该后缀"}
v.AddConfigPath("./") // 设置文件所在路径
v.Set("verbose", true) // 设置默认参数
if err := v.ReadInConfig(); err != nil {if _, ok := err.(viper.ConfigFileNotFoundError); ok {panic("Config file not found; ignore error if desired")
} else {panic("Config file was found but another error was produced")
}
}
// 监控配置和重新获取配置
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {fmt.Println("Config file changed:", e.Name)
})
return v
}
步骤三:演示:
启动服务,通过 postman 调用 http://127.0.0.1:8080/getConfig 可以获得如下参数:
这个时候把 yml 文件中的 version 修改成 3.0。这个时候后台会打印输出一句
Config file changed: /Users/Keil/GoLang/src/tutorials/viper/config.yml
这是因为我在代码中调用了两个关键的函数,WatchConfig 和 OnConfigChange。函数 OnConfigChange 打印输出了这句,输出代码:fmt.Println("Config file changed:", e.Name)
关于这两个函数的源码解析和工作原理,可以参考【https://blog.csdn.net/HYZX_99…】。里面介绍的比较详细。这里只是介绍如何使用。
此时再次调用接口,配置信息会变成如下:
4. 资料链接
- Viper 简介
- go 基于 viper 实现配置文件热更新及其源码分析