1 viper概述
viper是Go应用程序的完整配置解决方案。在构建现代化应用程序的过程中,开发人员可以通过使用viper而不必考虑配置文件的格式问题,可以被认为是所有应用程序配置需求的注册表。它支持功能:
- 设置默认值
- 从JSON,TOML,YAML,HCL和Java属性配置文件中读取
- 实时观看和重新读取配置文件(可选)
- 从环境变量中读取
- 从远程配置系统(etcd或Consul)读取,并观察变化
- 从命令行标志读取
- 从缓冲区读取
- 设置显式值
viper提供的配置方式的优先级顺序如下(由高到低):
- (1) 设置显示调用(explicit call to Set)
- (2) 命令行标志(flag)
- (3) 环境变量(env)
- (4) 配置文件(config)
- (5) 远程键/值存储(key/value store)
- (6) 默认值(default)
viper支持在运行时让应用程序实时读取配置文件,使应用程序一直使用最新修改的配置文件,从而不需要再重启服务。
2 解析常用配置文件示例
示例展示读取yaml、toml、json配置到对象,并且实时监听更新配置文件变化。
文件目录如下:
.
├── conf.go
├── conf_test.go
├── conf.json
├── conf.toml
└── conf.yaml
yaml格式配置文件conf.yaml内容如下:
# 服务名称
serverName: "my server"
# 监听地址
serverPort: 8080
# 运行模式,dev:开发环境,prod:正式环境
runMode: "dev"
# 是否开启性能分析功能,true:开启,false:关闭
isEnableProfile: true
# 输出日志级别 debug, info, warn, error
logLevel: "debug"
# Etcd集群地址
etcdEndpoints:
- "127.0.0.1:23791"
- "127.0.0.1:23792"
- "127.0.0.1:23793"
# mysql配置
mysqlURL: "root:123456@(127.0.0.1:3306)/user?charset=utf8&parseTime=true"
# mongodb配置
mongoURL: "mongodb://test:123456@127.0.0.1:27017/test"
# redis配置
redis:
addr: "127.0.0.1:6379"
password: "123456"
db: 0
# 字典
servers:
Beijing:
addr: "127.0.0.1"
port: "20060"
Shanghai:
addr: "127.0.0.1"
port: "20061"
toml格式配置文件conf.toml内容如下:
# 服务名称
serverName = "my server"
# 监听地址
serverPort = 8080
# 运行模式,dev:开发环境,prod:正式环境
runMode = "dev"
# 是否开启性能分析功能,true:开启,false:关闭
isEnableProfile = true
# 输出日志级别 debug, info, warn, error
logLevel = "debug"
# Etcd集群地址
etcdEndpoints = ["127.0.0.1:23791", "127.0.0.1:23792", "127.0.0.1:23793"]
# mysql配置
mysqlURL = "root:123456@(127.0.0.1:3306)/user?charset=utf8&parseTime=true"
# mongodb配置
mongoURL = "mongodb://test:123456@127.0.0.1:27017/test"
# redis配置
[redis]
addr = "127.0.0.1:6379"
password = "123456"
db = 0
# 字典
[servers]
[servers.Beijing]
addr = "127.0.0.1"
port = "20060"
[servers.Shanghai]
addr = "127.0.0.1"
port = "20061"
json格式配置文件conf.json内容如下:
{
"serverName":"my server",
"serverPort":8080,
"runMode":"dev",
"isEnableProfile":true,
"logLevel":"debug",
"etcdEndpoints":[
"127.0.0.1:23791",
"127.0.0.1:23792",
"127.0.0.1:23793"
],
"mysqlURL":"root:123456@(127.0.0.1:3306)/user?charset=utf8&parseTime=true",
"mongoURL":"mongodb://test:123456@127.0.0.1:27017/test",
"redis":{
"addr":"127.0.0.1:6379",
"password":"123456",
"db":0
},
"servers":{
"Beijing":{
"addr":"127.0.0.1",
"port":"20060"
},
"Shanghai":{
"addr":"127.0.0.1",
"port":"20061"
}
}
}
解析配置文件conf.go内容如下:
package config
import (
"path"
"strings"
"github.com/spf13/viper"
)
var conf = new(Conf)
// Conf 服务配置信息
type Conf struct {
// 服务名称
ServerName string `json:"serverName" toml:"serverName"`
// 服务端口
ServerPort int `json:"serverPort" toml:"serverPort"`
// 运行模式
RunMode string `json:"runMode" toml:"runMode"`
// 是否开启go profile
IsEnableProfile bool `json:"isEnableProfile" toml:"isEnableProfile"`
// 输出日志级别
LogLevel string `json:"logLevel" toml:"logLevel"`
// Etcd集群地址
EtcdEndpoints []string `json:"etcdEndpoints" toml:"etcdEndpoints"`
// mysql配置
MysqlURL string `json:"mysqlURL" toml:"mysqlURL"`
// mongodb配置
MongoURL string `json:"mongoURL" toml:"mongoURL"`
// redis配置
Redis *RedisConf `json:"redis" toml:"redis"`
// log配置
Servers map[string]*Servers `json:"servers" toml:"servers"`
}
// RedisConf Redis配置信息
type RedisConf struct {
Addr string `json:"addr" toml:"addr"`
Password string `json:"password" toml:"password"`
DB int `json:"db" toml:"db"`
}
// Servers 服务地址
type Servers struct {
Addr string `json:"addr" toml:"addr"`
Port string `json:"port" toml:"port"`
}
// Get 获取配置对象
func Get() *Conf {
return conf
}
// ParseConfig 解析配置文件到对象,包括yaml、toml、json等文件
func ParseConfig(filePath string, fileName string) error {
viper.AddConfigPath(filePath) // 路径
viper.SetConfigName(fileName) // 名称
viper.SetConfigType(strings.TrimLeft(path.Ext(fileName), ".")) // 从文件名中获取配置类型
err := viper.ReadInConfig()
if err != nil {
return err
}
err = viper.Unmarshal(conf)
if err != nil {
return err
}
// 监听配置文件更新
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
viper.Unmarshal(conf)
})
return nil
}
conf_test.go文件内容如下:
package config
import (
"testing"
"github.com/k0kubun/pp"
)
func TestParseYAML(t *testing.T) {
err := ParseConfig("./", "conf.yaml") // 解析yaml文件
if err != nil {
t.Error(err)
return
}
pp.Println(Get())
}
func TestParseTOML(t *testing.T) {
err := ParseConfig("./", "conf.toml") // 解析toml文件
if err != nil {
t.Error(err)
return
}
pp.Println(Get())
}
func TestParseJSON(t *testing.T) {
err := ParseConfig("./", "conf.json") // 解析json文件
if err != nil {
t.Error(err)
return
}
pp.Println(Get())
}
// 测试更新配置文件
func TestWatch(t *testing.T) {
err := ParseConfig("./", "conf.yaml")
if err != nil {
t.Error(err)
return
}
for i := 0; i < 30; i++ {
fmt.Println("port:", Get().ServerPort)
time.Sleep(time.Second)
}
}
经过测试,yaml、toml、json这三个文件解析结果都是一致的。
参考:https://blog.csdn.net/cs380637384/article/details/81217767
专题「golang相关」的其它文章 »
- 使用开发框架sponge快速把单体web服务拆分为微服务 (Sep 18, 2023)
- 使用开发框架sponge一天多开发完成一个简单版社区后端服务 (Jul 30, 2023)
- 一个提高开发项目效率的开发框架sponge,支持mysql、mongodb、postgresql、tidb、sqlite (Jan 06, 2023)
- go test命令 (Apr 15, 2022)
- go应用程序性能分析 (Mar 29, 2022)
- channel原理和应用 (Mar 22, 2022)
- go runtime (Mar 14, 2022)
- go调试工具 (Mar 13, 2022)
- cobra (Mar 10, 2022)
- grpc使用实践 (Nov 27, 2020)
- 根据服务名称查看golang程序的profile信息 (Sep 03, 2019)
- go语言开发规范 (Aug 28, 2019)
- goroutine和channel应用——处理队列 (Sep 06, 2018)
- golang中的context包 (Aug 28, 2018)