配置文件熱更新是服務(wù)器程序的一個基本功能,通過熱更新可以不停機(jī)調(diào)整程序的配置,特別是在生產(chǎn)環(huán)境可以提供極大的便利,比如發(fā)現(xiàn)log打得太多了可以動態(tài)調(diào)高日志等級,業(yè)務(wù)邏輯參數(shù)變化,甚至某個功能模塊的開關(guān)等都可以動態(tài)調(diào)整。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"os/signal"
"sync"
"syscall"
)
//用json配置測試
type Config struct {
Test1 string `json:"Test1:`
Test2 int `json:"Test1:`
}
var (
config *Config
configLock = new(sync.RWMutex)
)
func loadConfig() bool {
f, err := ioutil.ReadFile("config.json")
if err != nil {
fmt.Println("load config error: ", err)
return false
}
//不同的配置規(guī)則,解析復(fù)雜度不同
temp := new(Config)
err = json.Unmarshal(f, config)
if err != nil {
fmt.Println("Para config failed: ", err)
return false
}
configLock.Lock()
config = temp
configLock.Unlock()
return true
}
func GetConfig() *Config {
configLock.RLock()
defer configLock.RUnlock()
return config
}
func init() {
if !loadConfig() {
os.Exit(1)
}
//熱更新配置可能有多種觸發(fā)方式,這里使用系統(tǒng)信號量sigusr1實現(xiàn)
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGUSR1)
go func() {
for {
-s
log.Println("Reloaded config:", loadConfig())
}
}()
}
func main() {
select {}
}