在 Gin 框架中,r.Run()
方法是一个便捷的方法,用于启动 HTTP 服务器。然而,r.Run()
并没有实现优雅关闭(graceful shutdown)的功能。如果你需要实现优雅关闭服务器(例如,在接收到终止信号时完成正在处理的请求并关闭服务器),你需要使用标准库中的 http.Server
和上下文管理功能来实现。
以下是一个实现优雅关闭的示例:
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
)
func main() {
// 创建 Gin 实例
r := gin.Default()
// 定义路由
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello, World!")
})
// 创建自定义的 http.Server
srv := &http.Server{
Addr: ":8080",
Handler: r,
}
// 在 Goroutine 中启动服务器
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
log.Println("Server is running on http://localhost:8080")
// 等待终止信号(如 Ctrl+C 或系统信号)
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
// 创建上下文,用于设置关闭服务器的超时时间
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 关闭服务器
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server forced to shutdown:", err)
}
log.Println("Server exiting")
}
代码说明:
- 创建自定义
http.Server
:使用&http.Server{}
手动创建服务器对象,传递 Gin 的r
作为Handler
。 - 捕获信号:使用
os/signal
捕获SIGINT
和SIGTERM
信号(如Ctrl+C
)。 优雅关闭:
- 使用
context.WithTimeout
设置超时时间。 - 调用
srv.Shutdown(ctx)
确保正在处理的请求有时间完成。
- 使用
- 强制关闭:如果在超时后还未成功关闭,可以使用
log.Fatal
强制退出。
这种方式可以确保你的 Gin 应用在关闭时不会中断正在进行的请求,从而提升用户体验和服务的可靠性。