实现viper.remoteConfigFactory接口

type remoteConfigProvider struct{}

//这个接口是在第一次读取远程配置时调用,viper.ReadRemoteConfig()
func (rc remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) {
	log.Println("Getting config from remote", rp)
	r := bytes.NewReader([]byte("{\"a\":1}"))
	time.Sleep(time.Second)
	return r, nil
}

//这个接口是在客户端调用viper.WatchRemoteConfig(), 只监听一次变化
func (rc remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) {
    //这里写你获取配置的方法
	log.Println("Watching config from remote", rp)
	s := fmt.Sprintf(`{"app":{"name":"test","version":%d}}`, time.Now().Unix())
	r := bytes.NewReader([]byte(s))
	time.Sleep(time.Second)
	return r, nil
}

//这个接口是在客户端调用viper.GetViper().WatchRemoteConfigOnChannel()时,监听多次变化
func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) {
	log.Println("Watching  Channel config from remote", rp)
	ch := make(chan *viper.RemoteResponse)
	go func() {
		//defer close(ch)  viper里面使用死循环来处理,如果关闭管道会返回nil, 而viper没有处理,会报painc,所以不用关闭,viper是想让你在整个生命周期都监听

        //这里写你获取配置的方法
		for i := 0; ; i++ {
			ch <- &viper.RemoteResponse{
				Value: []byte(fmt.Sprintf(`{"app":{"name":"test","version":%d}}`, time.Now().Unix())),
			}
			time.Sleep(time.Second)
		}

	}()
	return ch, nil
}

设置viper必要参数

func init() {
	viper.RemoteConfig = remoteConfigProvider{} //把我们写的provider设置好,否则监听不会生效
	viper.SupportedRemoteProviders = []string{"app"} //这里名称需要设置好,和下面添加的名称需要一致
}

使用viper

    viper.SetConfigType("json") //需要和返回的数据格式一致,不然无法解析
	viper.AddRemoteProvider("app", ":8080", "/aabb/cc") //app就是上面的SupportedRemoteProviders,viper内部会校验是否包含,后面两个参数根据自己的需求来填写
	viper.ReadRemoteConfig() //加载远程配置
	// viper.WatchRemoteConfig() //一次性监听配置,阻塞
	viper.GetViper().WatchRemoteConfigOnChannel() //一直监听,非阻塞