配置檔案修改後,要達到及時生效,熱加載的目的,那麼可以通過2種方式實作
- 定時器循環,檢視檔案更新時間,如果發現有修改,那麼重新加載
- 監聽信号,檔案更改後,發送信号,通過捕獲信号,再重新加載
例如,線上的應用日志級别為
info
,出現故障後,你需要開啟
debug
來排查日志,但是把日志級别改成
debug
,那麼你不得不重新開機應用,可能故障現象就不存在或不好重制了,而且重新開機服務可能會影響使用者體驗。
上一篇已經介紹了
通過定時器實作配置檔案熱更新,以下我就介紹另一種信号的方式來實作吧。
signal.go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"os/signal"
"syscall"
"time"
)
//全局自定義攔截
var intercept []Intercept
var filename string = "intercept.json"
type Intercept struct {
Url string `json:"url"`
Method string `json:"method"`
RespHeader map[string]string `json:"resp_header"`
RespBody interface{} `json:"resp_body"`
RespCode int `json:"resp_code"`
}
//讀取自定義響應檔案
func Read_resp() {
intercept_data, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatalln(err)
}
err = json.Unmarshal(intercept_data, &intercept)
if err != nil {
log.Fatalln(err)
}
}
func main() {
//初始讀取
Read_resp()
//監聽信号
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGUSR1)
go func() {
for {
select {
//擷取到信号,再次執行
case <-sig:
Read_resp()
}
}
}()
//循環列印
for {
time.Sleep(1 * time.Second)
if len(intercept) > 0 {
fmt.Println(intercept[0].RespBody)
}
}
}
配置檔案
intercept.json
[{
"url": "http://test.cloudcare.cn/api/v1/workspace/member/list",
"method": "get",
"resp_body": {"msg": "d"},
"resp_header": {"Content-Type": "application/json"},
"resp_code": 200
}]
運作程式後,我編輯配置檔案内容
resp_body
,然後手動給程序發送信号
先查找出運作程序的pid
[root@izbp152ke14timzud0du15z signal]# ps -ef|grep signal
root 27800 2688 0 15:58 pts/1 00:00:00 ./signal
root 27876 17301 0 15:58 pts/2 00:00:00 grep --color=auto signal
通過kill給程序發送信号
[root@izbp152ke14timzud0du15z signal]# kill -USR1 27800
程式捕獲到信号後,會重新讀取配置檔案
map[msg:d]
map[msg:d]
map[msg:d]
map[msg:d]
map[msg:ff]
map[msg:ff]
map[msg:ff]
map[msg:ff]
map[msg:ff]
map[msg:ff]
map[msg:dde]
map[msg:dde]