GO的Viper的问题,哪位大佬能帮我解答一下呀?

作者站长头像
站长
· 阅读数 10

目前使用的是直接读取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个回答
avatar
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)
        }
    }
}

answer image

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