GO的Viper的问题,哪位大佬能帮我解答一下呀?
目前使用的是直接读取app.ini配置文件,然后再映射,简单粗暴,但是问题就是不能实时动态修改,所以上网寻找解决方案,看到大家都推荐Viper,所以尝试了一下,但是发现了个问题,虽然能够动态获取到改变的值,但是这个值并没有在程序中生效哇,具体问题解释如下:
app.ini
[kafka]
TimeExec = 20
main.go:
func main() {
viper.SetConfigName("app")
viper.SetConfigType("ini")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
if err != nil {
log.Fatal("read config failed: %v", err)
}
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})
// 执行定时任务
ticker := time.NewTicker(viper.GetDuration("kafka.TimeExec"))
defer ticker.Stop()
for {
select {
case <-ticker.C:
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
fmt.Println("间隔:" + viper.GetDuration("kafka.TimeExec"))
}
}
}
启动程序,项目20s执行一次,并且打印出间隔 20s。
这时候当我更改了配置文件,改为10s,确实会监控到并且也会执行OnConfigChange打印信息、也会打印出:间隔:10s,但是定时还是20s执行一次呀,这是为什么呢?
回复
1个回答

test
2024-06-30
time.NewTicker
方法执行的时候创建了 ticker ,创建的时候指定了间隔时间,那么这个 ticker 就会以这个间隔时间执行。
最简单的修改思路是,当文件变更时,调用 Reset 方法重置 ticker 的间隔时间。
func main() {
viper.SetConfigName("app")
viper.SetConfigType("ini")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
if err != nil {
log.Fatal("read config failed: %v", err)
}
viper.WatchConfig()
// 执行定时任务
ticker := time.NewTicker(viper.GetDuration("kafka.TimeExec") * time.Second)
defer ticker.Stop()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
ticker.Reset(viper.GetDuration("kafka.TimeExec") * time.Second)
})
for {
select {
case <-ticker.C:
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
fmt.Println("间隔:", viper.GetDuration("kafka.TimeExec")*time.Second)
}
}
}
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容