Go服务应暴露/health端点,检查进程状态与关键依赖(如DB、Redis),返回200或503;需结合资源水位(如内存)与关键路径探活,避免仅依赖HTTP 200;同时集成Prometheus指标和panic防护机制。
Go 服务如何暴露健康检查端点(/health)
生产环境必须提供可被外部探测的健康状态接口,最常用的是 HTTP /health 端点。它不返回业务数据,只反映进程是否存活、关键依赖是否就绪。
用标准库即可实现,无需额外框架:
func healthHandler(w http.ResponseWriter, r *http.Request) {
// 检查本地状态:goroutine 数量、内存压力等(可选)
// 检查关键依赖:数据库 ping、Redis 连接、下游 HTTP 服务连通性
if err := db.Ping(); err != nil {
http.Error(w, "db unreachable", http.StatusServiceUnavailable)
return
}
if err := redisClient.Ping(r.Context()).Err(); err != nil {
http.Error(w, "redis unreachable", http.StatusServiceUnavailable)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}
注意:http.StatusServiceUnavailable(503)比 500 更准确,表示“暂时不可用”,适合监控系统自动降级或剔除流量。
为什么不能只靠 HTTP 200 判断服务正常
HTTP 200 只代表 handler 执行完没 panic,并不等于业务可用。常见陷阱包括:
-
db.Ping()成功但慢查询堆积,连接池耗尽 - Redis 连接正常,但
SET命令超时或返回MOVED重定向错误 - 依赖的 gRPC 服务响应 200,但实际返回了
status.Code == codes.Unavailable - 内存持续上涨,
runtime.ReadMemStats()显示HeapInuse接近上限
所以健康检查逻辑里必须包含「关键路径探活」+「资源水位快照」,例如:
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
if memStats.HeapInuse > uint64(800*1024*1024) { // 超 800MB
http.Error(w, "high memory usage", http.StatusServiceUnavailable)
return
}
如何用 Prometheus + /metrics 暴露运行时指标
Prometheus 是 Go 服务最主流的指标采集方案,需引入 prometheus/client_golang 并注册指标: