go gin viper读取配置并实现配置热加载

go的gin简单好上手,用了都说香,快速开发api应用这块,go的gin库确实没的说,今天分享的是通过viper库读取配置并实现配置热加载,在gin应用docker后:二进制+配置,这样的配置确实很高效。

话不多说,直接看项目结构:

接下来是各个文件源码。

config.yaml

app:
  name: my-gin-demo
  port: 9080
  descrition: hahaha
mysql:
  user: root
  psswd: root
  host: 0.0.0.0
  port: 3307
  db: test
redis:
  host: 1.1.1.1
  port: 6379
  db: 1

config.go

package main

type AppConfig struct {
	App   App   `json:"app"`
	Mysql Mysql `json:"mysql"`
	Redis Redis `json:"redis"`
}

type App struct {
	Name        string `json:"name"`
	Port        int    `json:"port"`
	Description string `json:"description"`
}

type Mysql struct {
	User   string `json:"user,omitempty"`
	Passwd string `json:"passwd,omitempty"`
	Host   string `json:"host,omitempty"`
	Port   int    `json:"port,omitempty"`
	DB     string `json:"db,omitempty"`
}

type Redis struct {
	Host string `json:"host,omitempty"`
	Port int    `json:"port,omitempty"`
	DB   int    `json:"db,omitempty"`
}

dynamicLoadConfig.go

package loadConfig

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

var GlobalConfig *viper.Viper

func init()  {
	log.Println("Loading configuration logics...")
	GlobalConfig = initConfig()
	go dynamicReloadConfig()
}

func initConfig() *viper.Viper {
	GlobalConfig = viper.New()
	GlobalConfig.SetConfigName("config")
	GlobalConfig.SetConfigType("yaml")
	GlobalConfig.AddConfigPath("conf/")

	err := GlobalConfig.ReadInConfig()
	if err != nil {
		log.Println(err)
	}

	return GlobalConfig
}

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

main.go

package main

import (
	"github.com/gin-gonic/gin"
	"go-dynamicReload/loadConfig"
	"net/http"
)

func main()  {
	r := gin.Default()

	r.GET("/ping", ping)
	r.GET("/config", getConfig)

	r.Run(":" + loadConfig.GlobalConfig.GetString("app.port"))
}

func ping(ctx *gin.Context)  {
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "pong",
	})
}

func getConfig(ctx *gin.Context)  {
	var app AppConfig
	err := loadConfig.GlobalConfig.Unmarshal(&app)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"msg": "load config error",
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": app,
	})
}

go.mod

module go-dynamicReload

go 1.19

require (
	github.com/fsnotify/fsnotify v1.6.0
	github.com/gin-gonic/gin v1.9.0
	github.com/spf13/viper v1.15.0
)

以下是部分测试结果:
api: /ping

api: /config

尝试更改配置,mysql:port 改为3306,可以看到是成功的:

以下为gin的后台console日志:

参考文档:

posted on 2023-03-17 11:07  进击的davis  阅读(478)  评论(0编辑  收藏  举报

导航