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日志:
参考文档: