通过信号实现配置文件热更新

配置文件修改后,要达到及时生效,热加载的目的,那么可以通过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]
上一篇:Tornado从入门到进阶 打造支持高并发的技术论坛


下一篇:通过定时器实现配置文件热更新