之前写了一个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, 进行测试

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