Fiber 框架需手动集成优雅停机:监听 SIGTERM/SIGINT 信号,另起 goroutine 调用 app.Shutdown() 并配合 context.WithTimeout 设置超时,避免阻塞和资源泄漏。

Fiber 框架本身不提供开箱即用的优雅停机(Graceful Shutdown)机制,必须手动集成信号监听与资源协调逻辑。 它不像 Spring Boot 那样内置 server.shutdown=graceful 或自动等待 HTTP 连接完成。直接调用 os.Exit(0) 或被 kill -9 终止,会导致正在处理的请求中断、数据库连接泄漏、未 flush 的日志丢失等典型问题。
如何监听 SIGTERM 并触发 Fiber 应用关闭
Fiber 默认不响应系统信号,需显式注册 os.Signal 监听器,并在收到 SIGTERM(Kubernetes、systemd、Docker stop 默认发送)时启动关闭流程:
- 使用
signal.Notify订阅os.Interrupt和syscall.SIGTERM - 避免在信号 handler 中直接调用
app.Shutdown()—— 它是同步阻塞的,应另起 goroutine 执行 - 推荐配合
context.WithTimeout控制最大等待时间,防止无限 hang 住
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
go func() {
<-sigChan
log.Println("Received shutdown signal, starting graceful shutdown...")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := app.Shutdown(ctx); err != nil {
log.Printf("Shutdown error: %v", err)
}
}()
app.Shutdown() 调用前必须确保资源可安全释放
app.Shutdown() 仅负责停止 Fiber 的 HTTP server,它不会自动关闭你手动创建的数据库连接池、Redis 客户端、消息队列消费者等。这些资源必须在 app.Shutdown() 调用前显式释放,否则会卡住或泄漏:
- 调用
db.Close()(如sql.DB.Close())、rdb.Close()(Redis)、amqpConn.Close()(RabbitMQ)等方法 - 若使用依赖注入(如 Wire/Fx),应在 shutdown hook 中按依赖顺序反向清理(先关消费者,再关连接池)
- 注意:Fiber 的
app.Use中注册的中间件若启用了长生命周期 goroutine(如轮询、定时任务),需自行提供Stop()方法并在此处调用
常见错误:HTTP 请求仍在处理却已关闭监听套接字
即使你调用了 app.Shutdown(),如果没在调用前主动拒绝新连接,部分请求仍可能在 shutdown 过程中被 accept 进来,导致 panic 或超时。正确做法是:
- 在收到信号后,立即调用
app.Listener().Close()(仅限http.Server场景)或更稳妥地——使用net.Listener包装层做连接拦截 - 更推荐方式:在 Kubernetes 环境中,配合 readiness probe 下线 + preStop hook 延迟,让流量先从 service 层切断,再执行 shutdown
- 不要依赖
app.Shutdown()自动“等待活跃请求结束”——Fiber 不维护活跃连接计数,它只等 listener 关闭和 server.Serve() 返回
Docker/K8s 环境下必须配置 preStop 和 terminationGracePeriodSeconds
容器编排平台默认发送 SIGTERM 后立刻发 SIGKILL(K8s 默认 30 秒),若你的 shutdown 逻辑耗时超过该窗口,会被强制终止。必须显式声明缓冲期:
- Kubernetes:
terminationGracePeriodSeconds: 45(建议 ≥ 应用内context.WithTimeout设置) - Docker:
--stop-timeout=45参数,否则docker stop默认只等 10 秒 - 同时配置
lifecycle.preStop.exec.command执行轻量级通知(如 curl /healthz 探针下线),但核心 shutdown 逻辑仍应在 Go 进程内完成
真正关键的是:Fiber 的优雅停机不是配置出来的,而是靠你写清楚「哪些资源要关」「按什么顺序关」「超时怎么兜底」——没有魔法,只有显式的上下文控制与资源生命周期管理。


















