健康检查接口应返回200状态码及结构化JSON响应,包含进程存活与关键依赖(如Redis)的实时状态;Redis检查需异步缓存结果,避免阻塞,使用Do()配合短超时复用连接池,状态变量需原子保护,liveness与readiness探针须分离配置。

健康检查接口该返回什么状态码和结构
服务健康检查不是写个 /health 返回 “OK” 就完事。下游监控系统(比如 Prometheus、Kubernetes liveness probe)依赖明确的状态码和可解析的响应体。返回 200 是底线,但内容必须包含关键依赖的实时状态。
常见错误是把数据库连通性检查塞进主请求链路,导致每次调用 /health 都去连 Redis,拖慢整个探针响应——K8s 默认 1 秒超时,一连不上就重启 Pod。
- 只在
/health中做轻量级检查:进程存活 + 关键依赖连接池是否就绪(非真实 ping) - Redis 检查应走独立 goroutine 定期执行,结果缓存到内存变量,接口只读不阻塞
- 响应体建议用 JSON,字段如
{"status":"ok","redis":{"ok":true,"latency_ms":1.2}},避免纯文本或无结构字符串 - Kubernetes 中
livenessProbe和readinessProbe要分开配置:前者看进程是否卡死,后者才看 Redis 是否可用
用 redis.Client.Ping() 还是 redis.Client.Do() 测连通性
Ping() 看起来最直接,但它默认带 5 秒超时(由 redis.Options.DialTimeout 控制),且每次调用都新建 TCP 连接(如果连接池为空)。线上环境一旦 Redis 偶发延迟,Ping() 就拖垮健康接口。
真正稳定的做法是复用连接池里的空闲连接,用 Do() 发一个轻量命令,并显式控制超时。
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 优先用
client.Do(ctx, redis.NewBoolCmd("PING")).Err(),配合短超时 ctx(如 200ms) - 不要在健康接口里调
Ping();它适合初始化阶段验证配置,不适合高频探测 - 如果 Redis 开启了密码认证,
Ping()可能因 AUTH 未完成而失败,Do()则复用已认证连接,更真实 - 注意
Do()返回的error类型:网络错误(net.OpError)、超时(context.DeadlineExceeded)、Redis 协议错误要区分处理
定时检查怎么避免 Goroutine 泄漏和资源竞争
用 time.Ticker 启一个 goroutine 定期测 Redis 很常见,但容易漏掉两个关键点:goroutine 无法被取消、状态变量没加锁。
服务热重启或配置变更时,旧 ticker 不停,新 ticker 又起,多个 goroutine 并发写同一个健康状态变量,结果就是接口返回 “redis.ok: true” 但实际已断连。
- 用
context.WithCancel包裹 ticker 循环,收到 shutdown 信号时主动 stop ticker - 健康状态变量(如
redisHealthy bool)必须用sync/atomic或sync.RWMutex保护,不能裸写 - 别在 ticker 循环里打日志 —— 每秒一次的 “Redis OK” 日志会刷爆磁盘;只在状态翻转时(true→false 或 false→true)记录
- 初始连接失败时,别让 ticker 直接 panic;应设默认状态为 false,等第一次成功才切 true
为什么不能只依赖 redis.Conn.Ping() 就认为 Redis 可用
redis.Conn.Ping()(底层 net.Conn 的方法)只确认 TCP 层通了,不代表 Redis 进程在响应、没 OOM、没被防火墙限流、没卡在 slowlog 里。线上出过多次 “Ping 通但 SET 超时” 的 case。
真实可用意味着:能发命令、能收响应、延迟在业务容忍范围内。
- 必须用客户端库的真实命令(如
PING或INFO)走完整 Redis 协议栈,不能只测 socket 连通性 - 测完后顺手记下
time.Since(start),超过 100ms 就标为 degraded,避免把高延迟当正常 - 如果 Redis 是集群模式,
PING可能路由到任意节点;建议用CLUSTER INFO或打到特定 slot 的 key(如GET health:check)来覆盖分片逻辑 - 某些云 Redis(如阿里云 Tair)对
PING有特殊限流策略,单独压测该命令反而触发风控;换成EXISTS一个固定 key 更稳妥
健康检查不是越全越好,而是要在“足够反映真实问题”和“不给系统添负担”之间卡住那个临界点。Redis 连通性只是其中一环,背后连着连接池配置、超时设置、错误分类、状态同步——少一个环节,监控就可能给你演一出“假阳性”。

















