之前写了一个Gin项目, 把一些秘钥写在配置文件中, 然后由于aws的策略问题, 这些秘钥需要定期更新, 在之前, 我需要更改完秘钥后, 重新启动程序来读取更改后的key.这样非常不优雅
所以去看了gin的官方文档, 了解一下如何捕获信号然后处理, 现在可以实现给程序发一个HUP 信号, 就让程序读取配置文件而不用重启程序, 非常方便
下面上代码
//创建一个信号管道
signalChannel := make(chan os.Signal, 1)
go func() {
//这个例程启动gin服务, 如果接收到退出信号, 就会调用err != nil后的逻辑,然后延迟关闭管道,让main函数退出
defer close(signalChannel)
if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("关闭gin服务错误:%v", err)
}
}()
defer func() {
//延迟关闭redis的连接
global.R.Close()
//延迟关闭db的连接
db, _ := global.DB.DB()
db.Close()
}()
//这里会注册一个监听服,会捕获给定的3个信号量送入到给定的管道
signal.Notify(signalChannel, syscall.SIGHUP, syscall.SIGTERM, os.Interrupt)
//循环读取信号管道内的信号,如果是退出信号,调用shutdown函数关闭http服务,关闭管道,退出程序.
//如果是HUP信号,重读配置文件
for _sig := range signalChannel {
switch _sig {
case syscall.SIGHUP:
global.Logger.Info("接收到重读配置文件信号,开始重新读取配置文件")
err := setupSetting()
if err != nil {
global.Logger.Fatalf("重读配置文件异常: %v,gin服务将退出", err)
}
global.Logger.Info("重新读取配置文件成功")
case os.Interrupt:
global.Logger.Infof("接受到interrupt信号,gin服务将退出")
s.Shutdown(global.Ctx)
case syscall.SIGTERM:
global.Logger.Infof("接受到-15信号,gin服务将退出")
s.Shutdown(global.Ctx)
default:
continue
}
}
log.Println("gin服务退出....")
接下来我们就要实现一个功能, 就是让我的systemd服务文件支持reload功能,类似于systemctl reload nginx这样
编辑我们的服务文件, 添加一行
ExecReload=/bin/kill -HUP $MAINPID
然后重载systemd, 进行测试

可以看到成功接收到了信号, 非常的完美
发表回复