必须用 Beego 路由(如 beego.Get)注册健康检查接口,而非 http.HandleFunc;推荐使用 toolbox.HealthCheckHandler 实现可扩展、带缓存与超时控制的多维度检查,/health 仅做轻量就绪探测,/healthcheck 用于详细诊断。

Beego 框架里实现健康检查接口,不能用 http.HandleFunc 直接注册,否则会绕过 Beego 的路由中间件、日志、上下文和 HTTPS 重定向逻辑,导致 Consul 或 Kubernetes 探针收不到响应,或返回 404。
必须用 Beego 路由注册,而不是裸 http.ServeMux
Beego 的 beego.Router 或 beego.Get 才能确保请求走完整生命周期:中间件链、配置的 EnableDocs、RecoverPanic、CORS 等都会生效。裸 http.HandleFunc 完全脱离这套机制。
- 正确写法:
beego.Get("/health", func(ctx *context.Context) { ctx.Output.Body([]byte("OK")) }) - 错误写法:
http.HandleFunc("/health", ...)—— 即使监听端口一致,路径也不被 Beego 管理 - 若使用
beego.Run()启动,所有健康检查必须走 Beego 路由;若手动调http.ListenAndServe,等于弃用 Beego 的 HTTP 层,不推荐
Beego toolbox.HealthCheck 是更规范的可扩展方案
Beego 自带的 toolbox 模块提供了插件式健康检查能力,支持多检查项聚合、状态缓存、TTL 控制,比手写单一路由更健壮。
- 先定义检查器,如
DatabaseCheck实现Check() error方法 - 注册:
toolbox.AddHealthCheck("database", &DatabaseCheck{}) - 统一暴露端点:
beego.Get("/healthcheck", toolbox.HealthCheckHandler) - 响应示例:
*database: OK或*database: can't connect database,便于运维肉眼识别 - 注意:
toolbox.HealthCheckHandler默认不带超时控制,若某个Check()阻塞,整个接口卡住;建议在Check()内自行加context.WithTimeout
/health 和 /healthcheck 的分工要明确
Kubernetes 或 Consul 的探针路径必须轻量、无依赖、低延迟;而详细诊断应走另一条路径,避免把 readiness probe 变成链路探测。
-
/health:只确认 Beego 应用已启动、配置加载完成、关键全局变量就绪(如isAppReady.Load() == true),返回 200 即可,响应时间控制在 10ms 内 -
/healthcheck:由运维或调试人员调用,可包含 DB ping、Redis 连通性、磁盘空间等耗时检查,适合带?verbose=true参数做临时诊断 - Consul 注册时填的
http字段必须和 Beego 路由完全一致,例如http://172.17.0.3:8080/health,且 Beego 必须监听:8080(非localhost:8080),否则 Consul Agent 访问不到
数据库检查别直接调 db.Ping()
在 Check() 方法里写 db.Ping() 是高频错误——它没有上下文超时,网络抖动时会阻塞数秒,拖垮整个健康检查端点。
- 改用
db.PingContext(ctx, 1*time.Second),其中ctx来自context.WithTimeout(parentCtx, 1*time.Second) - 不要复用业务
*sql.DB做健康检查;可新建一个最小化连接池:db.SetMaxOpenConns(1); db.SetMaxIdleConns(1) - PostgreSQL 用户优先用
pgxpool.Pool.Stat().AcquiredConns > 0替代 Ping,更快更准;MySQL 可执行db.QueryRowContext(ctx, "SELECT 1").Scan(&i) - Beego 的
toolbox不自动注入context,所以超时逻辑得自己在Check()里写死或传入
真正容易被忽略的是:Beego 的 toolbox.HealthCheckHandler 不做并发限制,如果同时有几十个探针请求进来,每个都触发一次 DB 检查,可能瞬间打爆连接池。生产环境务必加本地缓存 + TTL,比如用 sync.Map 存上一次检查结果,5 秒内不再重复执行。


















