Golang Signal使用

345 阅读1分钟

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{})
}