当 Gin 服务关闭时,希望协程也能优雅退出。
你可以使用 context.Context 来控制 goroutine 的生命周期,同时监听系统信号来优雅地关闭 Gin 服务和后台任务。
✅ 示例:Gin 服务退出时,协程优雅退出
package main
import (
"context"
"fmt"
"github.com/gin-gonic/gin"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
// 创建 context,传递退出信号给 goroutine
ctx, cancel := context.WithCancel(context.Background())
// 启动后台任务
go backgroundWorker(ctx)
// 启动 Gin 服务
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "pong"})
})
srv := &http.Server{
Addr: ":8080",
Handler: router,
}
// 启动服务(非阻塞)
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
log.Println("Server started on :8080")
// 监听终止信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutdown signal received")
// 通知协程退出
cancel()
// 优雅关闭 HTTP 服务
ctxTimeout, cancelTimeout := context.WithTimeout(context.Background(), 5*time.Second)
defer cancelTimeout()
if err := srv.Shutdown(ctxTimeout); err != nil {
log.Fatal("Server Shutdown:", err)
}
log.Println("Server exited properly")
}
// 模拟后台协程任务
func backgroundWorker(ctx context.Context) {
log.Println("Background worker started")
for {
select {
case <-ctx.Done():
log.Println("Background worker received stop signal")
return
default:
// 模拟任务执行
fmt.Println("Background task running...")
time.Sleep(2 * time.Second)
}
}
}
🧠 核心点说明:
| 功能 | 实现方式 |
|---|---|
| 后台任务控制 | context.Context |
| 监听退出信号 | os/signal + syscall |
| Gin 优雅关闭 | http.Server.Shutdown |
| 协程安全退出 | select + <-ctx.Done() |
最后
以上就是岁月静好最近收集整理的关于gin服务退出同时优雅退出协程示例的全部内容,更多相关gin服务退出同时优雅退出协程示例内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复