Buffalo 默认不提供健康检查端点,需手动注册 /health 路由并返回 application/json 格式响应;否则 Kubernetes liveness probe 会失败导致容器反复重启。

Buffalo 默认不提供 /health 或 /healthz 这类开箱即用的健康检查端点,必须手动注册路由并返回标准响应——否则 Kubernetes liveness probe 会持续失败,容器反复重启。
为什么不能依赖 Buffalo 内置机制
Buffalo 的 app.Routes() 不含健康检查,buffalo dev 启动时也不会自动挂载。它连 GET / 都只是渲染模板,更不会默认返回 200 OK + JSON。如果你在 K8s 中配置了 livenessProbe.httpGet.path: /health,而没自己实现,Pod 就会卡在 CrashLoopBackOff。
最简可行的健康检查路由写法
在 app.go 的 func App() 末尾、return app 前插入:
app.GET("/health", func(c buffalo.Context) error {
return c.Render(200, r.JSON(map[string]string{"status": "ok"}))
})
- 别用
c.String():K8s probe 要求明确 Content-Type,r.JSON()自动设为application/json - 别返回
nil:Buffalo 会当成 200 + 空体,但某些 probe 实现(如 Istio)要求非空 body - 别加中间件:健康检查应绕过 auth、CORS、日志等所有业务逻辑层,避免因中间件 panic 导致误判
带数据库连接校验的增强版
仅返回 {"status": "ok"} 不够真实——你得确认 DB 是否可连。但注意:不能每次请求都建新连接,要用已初始化的 db 实例:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
app.GET("/health", func(c buffalo.Context) error {
if err := models.DB.Validate(); err != nil {
return c.Render(503, r.JSON(map[string]string{"status": "db_unavailable", "error": err.Error()}))
}
return c.Render(200, r.JSON(map[string]string{"status": "ok"}))
})
-
models.DB是pop.Connection,Validate()会发一条SELECT 1,轻量且可靠 - 别用
models.DB.RawQuery("SELECT 1").All():多一次序列化,无必要 - 别在 health handler 里调
tx := models.DB.Transaction():事务开销大,且未 commit 会拖慢连接池
生产环境必须注意的兼容性细节
Kubernetes 和 Envoy 对健康检查路径有隐式约定,硬编码 /health 可能和反向代理冲突:
- 若你用了
app.Group("/api/v1"),健康检查**不能**放在 group 下——它必须是根路径,否则 ingress controller 找不到 - 某些平台(如 Cloud Run)要求路径为
/healthz或/readyz,需同步改 route 并更新 infra 配置 - 别让
/health走 gzip 中间件:压缩小 JSON 得不偿失,还可能触发某些 LB 的 content-length 处理 bug
真正容易被忽略的是:这个端点一旦上线,就该纳入 CI 流程做自动化探测——不是靠人 curl,而是用 curl -f http://localhost:3000/health 加进 make test,否则下次改路由或中间件,没人知道它悄悄挂了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










