Signal
信号是进程间通信的一种方式,应用可以监听指定的信号来进行特殊的业务处理。
应用场景
举一个应用场景,线上出现BUG了,但是根据线上的INFO日志定位不出最终的原因,但是如果有DEBUG日志就可以提供一些更多的排查思路。我们可以监听指定信号,然后将线上的日志级别进行切换,这样就不用重启进程,对用户造成闪断影响。当然问题定位后,日志级别还是要切换成INFO的。
当然典型的应用场景就是监听指定信号实现进程的优雅退出。我们线上的业务进程重启,会通过脚本执行kill命令来进行stop,所以我们监听了Term信号,当然业务代码需要进行正常stop逻辑。下面代码是一个我们业务Signal的一个简单使用:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
type SignalHandler interface {
HandleSigHup()
HandleSigInt()
}
type MySignalHandler struct {
SignalHandler
}
func (this *MySignalHandler) HandleSigHup() {
// 将线上日志级别修改成DEBUG级别
...
}
func (this *MySignalHandler) HandleSigInt() {
fmt.Println("MySignalHandler HandleSigInt")
}
func signalRun(handler SignalHandler) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
for {
select {
case sign := <-c:
switch sign {
case syscall.SIGHUP:
if handler != nil {
handler.HandleSigHup()
}
case syscall.SIGINT:
if handler != nil {
handler.HandleSigInt()
}
default:
return
}
}
}
}
func main() {
signalRun(&MySignalHandler{})
}