Sniper 是 Bilibili 开源的一款轻量级业务框架,通过阅读其代码,可以学习到很多优秀的设计理念,这里学习的主要是其中 cmd/server/main.go 中关于停止、重载的设计,首先利用 viper.OnConfigChange 函数监听配置文件,发生更改后,则向 reload channel 发送消息,通过
signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)
监听syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP
三个信号,并将其发送给 stop channel。其后在 for loop 循环中,通过 select case 获取两个channel 中的消息,进行相应的重制、停止等操作。
func main() {
reload := make(chan int, 1)
stop := make(chan os.Signal, 1)
conf.OnConfigChange(func() { reload <- 1 })
conf.WatchConfig()
signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)
startServer()
for {
select {
case <-reload:
util.Reset()
case sg := <-stop:
stopServer()
// 仿 nginx 使用 HUP 信号重载配置
if sg == syscall.SIGHUP {
startServer()
} else {
util.Stop()
return
}
}
}
}