天天看點

通過信号實作配置檔案熱更新

配置檔案修改後,要達到及時生效,熱加載的目的,那麼可以通過2種方式實作

  1. 定時器循環,檢視檔案更新時間,如果發現有修改,那麼重新加載
  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]      

繼續閱讀