概述
我的项目启动必定少不了配置文件,个别咱们会放在独自的目录,例如 config
中,有 yaml、ini、json 等等格局,个别用开源的读取相应问的文件映射到构造体中。
然而当一个我的项目秒杀频繁管制库存和限流策略等、或者其余须要频繁的变更配置文件的时候,就须要频繁的更改代码,打包,上线。工夫老本高,实效性也低。所以个别都做配置热更新。
做配置热更新的有很多 consul、Firestore、etcd、也有 redis 等等 KV 存储,明天咱们要讲的是 viper 和 etcd 的热更新操作
筹备工作
我用的是 mac m1
装置 etcd
生产环境必定就是集群,测试咱们间接单机模式了
brew install etcd
启动
etcd
测试
$ etcdctl version
etcdctl version: 3.5.5
API version: 3.5
或者 docker,k8s 装置测试环境
viper
go get github.com/spf13/viper
应用配置文件
func configByFile(vp *viper.Viper){
var err error
// 设置配置文件的名字
vp.SetConfigName("config") // name of config file (without extension)
// 设置配置文件后缀
vp.SetConfigType("json") // REQUIRED if the config file does not have the extension in the name
// 设置配置文件的门路
vp.AddConfigPath("/Users/xxxx/Desktop/test/testCode/") // path to look for the config file in
vp.Set("verbose", true) // 设置默认参数
// 读取文件
if err = vp.ReadInConfig(); err != nil {if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; ignore error if desired
log.Fatal("not found")
} else {// Config file was found but another error was produced}
}
if err = vp.Unmarshal(&conf);nil != err{log.Fatal("Unmarshal",err)
}
fmt.Println(conf)
//watch
go func() {vp.OnConfigChange(func(e fsnotify.Event) {fmt.Println("Config file changed:", e.Name)
fmt.Println(e.String())
fmt.Println(e.Op.String())
})
vp.WatchConfig()}()}
配置文件产生批改等行为时候回接管到调用回调函数,做相应的解决
etcd 做配置
func configByEtcd(vp *viper.Viper){
var err error
if err = vp.AddRemoteProvider("etcd3", "http://127.0.0.1:2379", "/config/viper-test/config");err != nil {log.Fatal(err)
}
vp.SetConfigType("json")
if err = vp.ReadRemoteConfig();err != nil {log.Fatal(err)
}
if err = vp.Unmarshal(conf);err != nil {log.Fatal(err)
}
fmt.Println("获取的配置信息",conf)
//fmt.Println(vp.Get("addr"))
//fmt.Println(vp.Get("port"))
go watchRemoteConfig(vp)
select {}}
func watchRemoteConfig(vp *viper.Viper) {
for {time.Sleep(time.Second * 5) // delay after each request
// currently, only tested with etcd support
err := vp.WatchRemoteConfig()
if err != nil {log.Printf("unable to read remote config: %v", err)
continue
}
// unmarshal new config into our runtime config struct. you can also use channel
// to implement a signal to notify the system of the changes
if err = vp.Unmarshal(&conf); nil != err{log.Printf("unable to read remote config: %v", err)
continue
}
fmt.Println("获取的配置信息",conf)
}
}
批改 ercdkeeper 内容
查看后果
获取的配置信息 &{127.0.0.1 3307}
获取的配置信息 &{127.0.0.1 3307}
获取的配置信息 &{127.0.0.1 3307}
获取的配置信息 &{127.0.0.1 3306}
获取的配置信息 &{127.0.0.1 3306}
^Csignal: interrupt
能够看到扭转了 就收到了
上边只是一个简略的应用,更具体的利用能够本人封装下,还是很实用的
本文由 mdnice 多平台公布