Go HTTP 服务优雅关闭实践
wxk1991 Lv5

Go HTTP 服务优雅关闭实践

服务发布、容器重启、机器维护时,进程通常会收到退出信号。如果直接退出,正在处理的请求可能中断。优雅关闭可以让服务停止接收新请求,同时等待已有请求完成。


一、创建 Server

1
2
3
4
server := &http.Server{
Addr: ":8080",
Handler: mux,
}

不要只用 http.ListenAndServe,显式创建 Server 才方便控制关闭流程。


二、监听退出信号

1
2
3
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

在容器环境中,常见信号是 SIGTERM


三、调用 Shutdown

1
2
3
4
5
6
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

if err := server.Shutdown(ctx); err != nil {
log.Printf("shutdown error: %v", err)
}

Shutdown 会停止监听新连接,并等待已有请求结束,直到超时。


四、启动服务

通常在 goroutine 中启动服务:

1
2
3
4
5
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()

http.ErrServerClosed 是正常关闭时的返回值,不应该当成致命错误。


五、实践建议

优雅关闭时间不要无限长。一般设置 5 到 30 秒,根据业务请求耗时决定。关闭期间还可以停止后台任务、刷新日志、关闭数据库连接。

这类细节不显眼,但会显著提升服务发布时的稳定性。