健康检查接口必须暴露符合kubernetes约定的http handler:/healthz用于存活探针(仅检查进程存活,需快速响应),/readyz用于就绪探针(须同步探测关键依赖连通性并设≤3s超时),路径严格匹配、禁重定向、状态码驱动判断,且逻辑轻量无副作用。

健康检查接口必须暴露 HTTP handler,且路径要符合 Kubernetes 约定
Kubernetes 的 livenessProbe 和 readinessProbe 默认通过 HTTP GET 请求访问固定路径(如 /healthz 和 /readyz),Golang 模块中若不显式注册对应 handler,探针会直接返回 404,导致容器被误杀或无法进流量。
实操建议:
- 用
http.HandleFunc或http.ServeMux显式注册/healthz和/readyz,避免依赖中间件自动注入 - 路径名必须严格匹配 probe 配置,大小写敏感;
/health或/health-check不会被识别 - handler 内部不要做重定向(如
http.Redirect),Kubernetes 探针不跟随 302 - 返回状态码应为 200 表示成功,非 2xx(如 503)表示失败 —— Kubernetes 只看状态码,不解析响应体
就绪探针需检查依赖服务连通性,不能只返回硬编码的 OK
/readyz 的核心职责是判断应用是否已准备好接收外部流量。如果只返回静态 {"status":"ok"},即使数据库连接失败、Redis 超时、下游 gRPC 服务不可达,Kubernetes 仍会把请求路由过去,引发雪崩。
实操建议:
- 在
/readyzhandler 中同步执行关键依赖探测:调用db.PingContext()、redis.Ping()、grpcConn.Invoke(...)等 - 设置合理超时(建议 ≤3s),用
context.WithTimeout包裹每个依赖检查,防止阻塞整个 handler - 任一依赖失败即返回 503,并在响应体中写明失败项(如
{"error":"failed to connect to redis"}),便于排障 - 避免在就绪检查中执行耗时业务逻辑(如加载缓存、预热模型),这些应放在应用启动阶段完成
健康检查应轻量、无副作用,且与就绪检查逻辑分离
/healthz 是 liveness 探针目标,Kubernetes 用它判断进程是否存活。它必须快(通常
实操建议:
-
/healthz只检查进程内基础状态:goroutine 数量是否爆炸、内存是否接近上限(runtime.ReadMemStats)、本地锁是否死锁等 - 绝对不要在
/healthz中调用数据库、HTTP 外部服务或写磁盘 —— 这会让 liveness 变成“伪就绪”检查,失去设计本意 - 可复用部分工具函数(如时间戳、版本号),但逻辑路径必须和
/readyz完全隔离 - 若使用第三方库(如
go-health),确认其HealthChecker实现未隐式引入依赖检查;建议手写更可控
Probe 配置参数需与 Go handler 超时、启动时间对齐
Kubernetes 的 initialDelaySeconds、timeoutSeconds、periodSeconds 若设置不当,会导致探针频繁失败。例如 Go 应用启动耗时 8s,但 initialDelaySeconds: 5,前几次探针必 503;又如 handler 最大耗时 2.5s,但 timeoutSeconds: 2,必然超时。
实操建议:
- 测量真实启动耗时(从
main()开始到第一个 handler 可响应为止),设initialDelaySeconds≥ 该值 +2s 安全余量 -
timeoutSeconds必须 > handler 内最慢依赖的超时值(如db.PingContext(ctx, 2*time.Second)→ timeoutSeconds ≥ 3) -
periodSeconds建议设为 10–30,太短(如 3)易放大瞬时抖动;太长(如 120)故障发现延迟过高 - 在本地用
curl -v http://localhost:8080/readyz手动验证响应时间和状态码,再配 probe
真正难的不是写两个 endpoint,而是让就绪检查既足够严格(挡住坏实例),又不过度保守(避免误判);健康检查既要足够灵敏(及时发现僵死进程),又不能过于激进(把暂时卡顿当崩溃)。这些边界往往取决于你的依赖稳定性、超时策略和观测能力 —— 没有银弹,只有反复校准。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











