/livez 必须仅检查进程自身状态(如原子变量、goroutine 数、堆内存),严禁调用 DB 或外部服务;/readyz 可含缓存依赖探测;需独立轻量 HTTP server 或无中间件路由,路径严格匹配,K8s 探针参数须与 Go 代码超时和就绪逻辑对齐。

不难,但错配语义或绕不开中间件就真会重启到怀疑人生。
/livez 必须只查进程自身状态,别碰任何外部依赖
livenessProbe 失败 → K8s 杀容器 → 重新拉起。如果 /livez 里调了 db.PingContext 或 http.Get,DB 网络抖动 1 秒,Pod 就进 CrashLoopBackOff 循环——进程明明活着,却被当成“死了”反复干掉。
- 只允许检查:原子变量(
atomic.LoadInt32(&healthy))、goroutine 数(runtime.NumGoroutine()≤ 1000)、堆内存(mem.HeapInuse - 绝对禁止:
time.Sleep、os.ReadFile、net.Dial、redis.Ping、任何带 I/O 的操作 - 响应必须 ≤ 1 秒:注册 handler 前,给
http.Server显式设ReadTimeout: 5 * time.Second和WriteTimeout: 10 * time.Second,防 GC STW 卡住
/readyz 要查依赖,但必须缓存结果、并行探测、带超时
readinessProbe 失败 → 流量被摘,但进程继续跑。这里才是查 DB、Redis、gRPC 的地方,但不能每次请求都连一次——高频探针(比如 periodSeconds: 2)下,db.PingContext 会打爆连接池、拖垮数据库。
- 启动后台 goroutine,用
time.Ticker每 5 秒执行一次全量检查,结果存进sync.RWMutex保护的结构体 - handler 里只读快照,不触发新连接;失败时返回
http.StatusServiceUnavailable(503),不是 500 - 所有依赖必须并行探测:
db.PingContext、redis.Ping、grpcConn.GetState()共用同一个context.WithTimeout(ctx, 800 * time.Millisecond) - 快速过滤优先:
db.Stats().OpenConnections > 0为 false 就直接 503,不走 SQL 查询
路由和中间件必须绕开,别让日志/鉴权拖垮探针
很多 Go Web 框架(Gin/Echo)默认给所有路由套中间件。日志中间件每秒记一条 /readyz,日志卷撑爆;鉴权中间件可能触发 JWT 解析或远程校验;recover 中间件捕获 panic 是好意,但健康端点本就不该 panic。
- 用
http.ServeMux单独起一个轻量 server,绑定:8081,只挂/livez和/readyz - 若必须复用主服务 mux,注册时用
router.NoRoute(Gin)或echo.New().GET(Echo)新建无中间件子 router - 别写
ctx.String(200, "ok"),用ctx.AbortWithStatus(200)终止链路,跳过后续中间件 - 路径必须严格匹配:K8s 配置里写的是
path: /livez,代码里就不能是/healthz或/health
Kubernetes 探针参数要跟 Go 代码行为对齐
配置写得再标准,只要 timeoutSeconds 小于 handler 实际耗时,或者 initialDelaySeconds 小于程序真正就绪时间,照样误判。
-
initialDelaySeconds至少设为 15–30 秒:Go 应用常需加载配置、初始化 gRPC client、预热缓存,main() 启动后未必 ready -
timeoutSeconds必须 > handler 最坏响应时间,且 ≤ 1 秒:Go 侧/livez要保证 100ms 内返回,K8s 可设为 1;/readyz若缓存探测结果,也可设 1 -
failureThreshold别设成 1:DB 抖动 2 秒很常见,periodSeconds: 5+failureThreshold: 1就是一次失败即摘流量;推荐failureThreshold: 3 - 两个探针绝不能指向同一个 handler:语义混淆会导致滚动更新卡死或无限重启
真正麻烦的从来不是写几行 http.HandleFunc,而是把「进程是否卡死」和「业务是否可服务」拆清楚、把外部依赖的探测从实时调用变成带缓存的快照读、以及让 K8s 配置和 Go 代码在超时与状态上严丝合缝。漏掉任意一环,线上就不是“健康检查”,而是“自毁开关”。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











