接下来依次看一下各文件的主体内容:

# conf/base.yaml
service:
  redis:
    host: 127.0.0.1
    port: 6379

conf/base.yaml文件定义了配置项,包含redis的host及port信息。

# src/dynamic_config/dynamic_config.go
package dynamic_config

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

var GlobalConfig *viper.Viper

func init() {
	fmt.Printf("Loading configuration logics...n")
	GlobalConfig = initConfig()
	go dynamicConfig()
}

func initConfig() *viper.Viper {
	GlobalConfig := viper.New()
	GlobalConfig.SetConfigName("base")
	GlobalConfig.AddConfigPath("conf/")
	GlobalConfig.SetConfigType("yaml")
	err := GlobalConfig.ReadInConfig()
	if err != nil {
		fmt.Printf("Failed to get the configuration.")
	}
	return GlobalConfig
}

func dynamicConfig() {
	GlobalConfig.WatchConfig()
	GlobalConfig.OnConfigChange(func(event fsnotify.Event) {
		fmt.Printf("Detect config change: %s n", event.String())
	})
}

src/dynamic_config/dynamic_config.go定义了全局配置信息的加载及动态监控方法,init函数为初始化执行的脚本,initConfig为初始化当前配置,dynamicConfig为冬天监听,通过viper的内部方法WatchConfig实现。

# main.go
package main

import (
	"DynamicConfigDemo/src/dynamic_config"
	"fmt"
	"github.com/gin-gonic/gin"
)

func main() {
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default()
	r.GET("/ping", func(context *gin.Context) {
		fmt.Println("Current redis host is: ", dynamic_config.GlobalConfig.GetString("service.redis.host"))
		context.JSON(
			200, gin.H{
				"message": "You are welcome!",
			})
	})
	r.Run(":9292")
}

main.go为主函数,调用gin包定义web server服务,实现了一个简单的http server服务器,每次请求发送时会打印配置的redis host信息。