0

我正在尝试使用 golang viper 读取我的应用程序配置,并希望始终读取最新配置。请在下面找到我的代码

配置文件

package config

import (
    "github.com/spf13/viper"
    "log"
    "github.com/fsnotify/fsnotify"
    "time"
)

type Reader interface {
    GetAllKeys() []string
    Get(key string) interface{}
    GetBool(key string) bool
    GetString(key string) string
}

type viperConfigReader struct {
    viper *viper.Viper
}

var TestConfReader *viperConfigReader

func (v viperConfigReader) GetAllKeys() []string{
    return v.viper.AllKeys()
}

func (v viperConfigReader) Get(key string) interface{} {
    return v.viper.Get(key)
}

func (v viperConfigReader) GetBool(key string) bool {
    return v.viper.GetBool(key)
}

func (v viperConfigReader) GetString(key string) string {
    return v.viper.GetString(key)
}


func init() {
    v:= viper.New()
    v.SetConfigName("test")
    v.AddConfigPath("/tmp/")

    err := v.ReadInConfig()

    if err != nil {
        log.Panic("Not able to read configuration", err.Error())
    }

    TestConfReader = &viperConfigReader{
        viper: v,
    }

    go func() {
        for {
            time.Sleep(time.Second * 5)
            v.WatchConfig()
            v.OnConfigChange(func(e fsnotify.Event) {
                log.Println("config file changed", e.Name)
            })
        }
    }()
}

main.go

package main

import (
    "github.com/xxxx/xxxx/config"
    "log"
    "time"
)

func main() {

    conf := config.TestConfReader

    log.Println(conf.GetAllKeys())
    log.Println(conf.GetString("test1"))

    time.Sleep(20 * time.Second)

    log.Println(conf.GetString("test1"))
}

当主程序运行时,我尝试更新配置并希望看到 OnConfigChange 日志消息,但它从未出现。

我该如何修复这个程序?

有人可以提供一个使用 viper watchconfig 和 onconfigchange 方法来读取最新配置的例子吗

4

1 回答 1

2

ymonad评论是正确的,根据您的操作系统,您可能会遇到viper / fsnotify问题。

例如,我在 Mac OS X (Sierra) 上运行了您的示例代码,并注意到您描述的相同症状:当配置文件位于/tmpviperWatchConfig调用中时,不会导致调用 viperOnConfigChange函数。

但是,当我更改AddConfigPath为使用当前工作目录或我的主目录时,我确实会看到您的OnConfigChange函数中的日志记录。例如,尝试:

v.AddConfigPath("./")

我建议尝试不同的目录位置,看看这是否是某种 viper/fsnotify 错误或限制。出于某种原因,它似乎没有检测到/tmpMac OS X 上目录的更改,至少,它不适用于我的设置。我在 OS X 上找不到任何问题/tmp,但 fsnotify CONTRIBUTING.md确实提到了 Vagrant 下“共享”目录的限制,所以也许有一些文件系统配置不会触发通知:

注意:fsnotify 文件系统事件不会在共享文件夹中触发。测试通过使用 /tmp 目录绕过了这个限制。

WatchConfig此外,您不需要OnConfigChange通过 goroutine 继续调用。您可以完全消除 goroutine,只需将相关行移至init.

于 2017-02-06T02:17:29.303 回答