在 Go 中,可以使用操作系统的信号来实现优雅的启动和停止。具体来说,可以在程序中监听 SIGINT 和 SIGTERM 信号,在接收到这两个信号时,优雅地关闭程序。
和channel结合,实现优雅启停
func Run(r *gin.Engine, name string, addr string) {
// r := gin.Default()
// r.Run(":8080")
// 优雅的启停
srv := &http.Server{
Addr: addr,
Handler: r,
}
// 启动协程监听的服务
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalln(name, err)
}
}()
// 无缓冲的channel,阻塞协程
quit := make(chan os.Signal)
// SIGINT 用户发送INTR字符(Ctrl+C)触发
// SIGTERM 结束程序(可以被捕获、阻塞或忽略)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// 阻塞,监听到程序结束会结束阻塞
<-quit
log.Printf("%s Shutting Down project web server...\n", name)
// 程序结束后,有中断,执行一些退出的操作
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
// 优雅的去关闭一些服务,但是需要一些时间进行一些程序的处理
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("%s web server Shutdown, cause by : %v \n", name, err)
}
select {
case <-ctx.Done():
log.Printf("%s time out...\n", name)
}
log.Printf("%s web server stop success...\n", name)
}