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() {
<h3>app.Shutdown() 调用前必须确保资源可安全释放</h3>
<p><code>app.Shutdown()</code> 仅负责停止 Fiber 的 HTTP server,它不会自动关闭你手动创建的数据库连接池、Redis 客户端、消息队列消费者等。这些资源必须在 <code>app.Shutdown()</code> 调用前显式释放,否则会卡住或泄漏:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2747" title="Fiber框架 3.0.0"><img
src="https://img.php.cn/upload/manual/001/589/237/6a9a598d9727e711.png" alt="Fiber框架 3.0.0" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2747" title="Fiber框架 3.0.0" class="overflowclass">Fiber框架 3.0.0</a>
<p class="overflowclass">Fiber框架 3.0.0 版本源码包下载,适合从 Fiber v2 迁移到 v3、体验新绑定系统、HTTP 客户端、状态管理和迁移工具的开发者。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2747" title="Fiber框架 3.0.0" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 调用
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 的优雅停机不是配置出来的,而是靠你写清楚「哪些资源要关」「按什么顺序关」「超时怎么兜底」——没有魔法,只有显式的上下文控制与资源生命周期管理。










