Golang 配置文件熱加載

Golang 配置文件熱加載

通常我們更新應用程序的配置文件,都需要手動重啓程序或手動重新加載配置。重啓服務會造成服務的短暫不可以用。所以我們要實現配置文件的熱加載。實現這個的主要思路就是監聽這個配置文件是否有改動

主要實現代碼如下

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"sync"
	"time"
)

// Config 用json配置測試
type Config struct {
	filename       string
	lastModifyTime int64
	Key            string `json:"key"`
}

var (
	config     *Config
	configLock = new(sync.RWMutex)
)

func (config *Config) reload() {
	// 定時器
	ticker := time.NewTicker(time.Second * 5)
	for range ticker.C {
		// 打開文件
		func() {
			f, err := os.Open(GetConfig().filename)
			if err != nil {
				fmt.Printf("open file error:%s\n", err)
				return
			}
			defer f.Close()

			fileInfo, err := f.Stat()
			if err != nil {
				fmt.Printf("stat file error:%s\n", err)
				return
			}
			// 或取當前文件修改時間
			curModifyTime := fileInfo.ModTime().Unix()
			if curModifyTime > GetConfig().lastModifyTime {
				// 重新解析時,要考慮應用程序正在讀取這個配置因此應該加鎖
				// 使用了 configLock 全局鎖
				fmt.Print("cfg change, load new cfg\n")
				loadConfig()
				GetConfig().lastModifyTime = curModifyTime
			}
		}()
	}
}

func loadConfig() bool {
	fmt.Print("load cfg\n")

	f, err := ioutil.ReadFile(config.filename)
	if err != nil {
		fmt.Println("load config error: ", err)
		return false
	}

	//不同的配置規則,解析複雜度不同
	temp := new(Config)

	err = json.Unmarshal(f, &temp)
	if err != nil {
		fmt.Println("Para config failed: ", err)
		return false
	}

	temp.filename = GetConfig().filename
	temp.lastModifyTime = GetConfig().lastModifyTime
	fmt.Printf("now cfg:%#v\n", temp)
	configLock.Lock()
	config = temp
	configLock.Unlock()
	return true
}

// GetConfig ...
func GetConfig() *Config {
	configLock.RLock()
	defer configLock.RUnlock()
	return config
}

func init() {
	config = new(Config)
	config.filename = "config.json"
	if !loadConfig() {
		os.Exit(1)
	}

	//熱更新配置可能有多種觸發方式,這裏使用定時器實現
	go config.reload()
}

func main() {

	ticker := time.NewTicker(time.Second * 1)
	for range ticker.C {
		fmt.Printf("key:%s\n", GetConfig().Key)
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章