必须用Fiber原生路由注册健康检查接口,因http.HandleFunc会绕过中间件、丢失上下文、不被HTTPS重定向或CORS处理,导致K8s探针持续失败、ALB判为Unhealthy;正确做法是app.Get("/health", handler)并确保签名匹配func(fiber.Ctx) error。

健康检查接口必须用 Fiber 原生路由注册,不能用 http.HandleFunc,否则会绕过中间件、丢失上下文、被 HTTPS 重定向或 CORS 拦截,K8s probe 可能持续失败。
为什么不能直接用 http.HandleFunc 注册 /health
直接调用 http.HandleFunc("/health", handler) 会让请求完全脱离 Fiber 的生命周期:日志不记录、context.WithTimeout 不生效、依赖注入(如 DB 连接池)不可用,更关键的是——当应用启用了 TLS 重定向或 CORS 中间件时,该路径根本不会被处理,ALB 或 K8s 可能收不到响应,直接判定为 404 或超时。
常见错误现象:
- K8s readiness probe 连续失败,Pod 被反复摘除流量
- ALB 目标组里实例状态始终显示 “Unhealthy”,但手动
curl http://pod-ip:3000/health却能返回 200 - 响应头缺失
X-Request-ID、Content-Type等框架统一 header
正确做法始终是:
- 用
app.Get("/health", healthHandler)注册 - handler 函数签名严格匹配
func(fiber.Ctx) error - 若需访问全局状态(如 DB 实例),通过
app.Use(func(c fiber.Ctx) error { c.Locals("db", db); return c.Next() })注入,再在 handler 中用c.Locals("db")获取
如何写一个安全、低开销的 /health handler
健康检查不是监控面板,它必须毫秒级返回,且不能因下游故障拖垮自身。直接在 handler 里调用 db.Ping() 是高危操作——它会阻塞 goroutine,且无超时控制;若数据库卡住,整个探针就 hang 死,K8s 会在几秒内连续失败并驱逐 Pod。
实操建议:
- 只做内存态检查:验证
app.State() == fiber.StateStarted或读取一个原子布尔标志atomic.LoadUint32(&readyFlag) == 1 - 如需检查 DB,务必用
context.WithTimeout包裹db.PingContext,超时设为1s(比 K8stimeoutSeconds至少短 1 秒) - 避免复用主连接池;可单独初始化一个轻量
sql.DB,调用SetMaxOpenConns(1)和SetMaxIdleConns(1) - PostgreSQL 推荐用
pgxpool.Pool.Stat().AcquiredConns > 0替代 Ping,MySQL 可用db.QueryRowContext(ctx, "SELECT 1").Scan(&_)
Fiber v3 下 /health 和 /ready 的语义分离实践
Fiber 本身不强制区分 /health 和 /ready,但 K8s 的 livenessProbe 和 readinessProbe 行为完全不同:前者失败会重启容器,后者只是摘流量。混用同一接口极易导致误重启。
典型分法:
-
/health:只确认进程存活,例如c.SendStatus(fiber.StatusOK),不做任何外部依赖检查 -
/ready:检查是否准备好服务请求,例如 DB 连通、Redis 可写、本地缓存已加载;若未就绪,返回c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{"status": "not ready"}) - 两者都应返回 JSON,但
/health必须始终是 200;/ready在启动初期返回 503 是合理且推荐的
注意:Fiber v3 要求 Go 1.25+,若项目还在用 Go 1.24,升级前先确认所有依赖兼容性——尤其是自定义中间件中对 fasthttp.Request 的直接操作,v3 对底层 Request/Response 封装有调整。
ALB 或 K8s 配置健康检查时的关键参数对齐
后端 Fiber 服务写好了,但 ALB 或 K8s 的探测配置没对齐,照样会判为不健康。最常踩的坑是协议和路径不一致。
ALB 目标组健康检查设置要点:
- 检查方式选
HTTP(非 TCP),路径填/health或/ready,不要漏掉开头的/ - 健康阈值(Healthy threshold)建议 ≥3,避免网络抖动误判;不健康阈值(Unhealthy threshold)建议 ≥2
- 响应超时(Response timeout)必须 > 后端 handler 的实际耗时,但 < K8s 的
timeoutSeconds(通常设为 2–3s) - 若用 HTTPS 检查,确保后端证书有效,且 ALB 安全策略允许 TLS 1.2+
K8s readinessProbe 示例片段:
readinessProbe:
httpGet:
path: /ready
port: 3000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 2
这里 timeoutSeconds: 3 意味着后端 handler 必须在 3 秒内返回,而你的 db.PingContext 超时就得设成 ≤2s,否则必然失败。


















