← 中文资源

简体中文版本

为 gRPC 服务添加健康检查探针

注册标准 grpc.health.v1 服务,用 grpc-health-probe 配置 Kubernetes 探针,并在优雅关闭时切换为 NOT_SERVING。

阅读英文原文

概述

TCP 探针只能证明端口可连接,无法反映 gRPC 服务是否真正就绪。数据库连接池未初始化、迁移未完成时,Pod 仍可能被加入 Endpoints 并接收请求。标准 grpc.health.v1.Health 服务提供了跨语言的健康协议,配合 grpc-health-probe 即可让 Kubernetes 获得准确的就绪与存活信号。

步骤

  1. 在启动 gRPC Server 时注册健康服务,并为具体服务名设置状态:
hs := health.NewServer()
healthpb.RegisterHealthServer(grpcServer, hs)
hs.SetServingStatus("payments.v1.Payments", healthpb.HealthCheckResponse_SERVING)
  1. 用 exec 探针替换原来的 TCP 探针。就绪探针检查具体服务名,存活探针检查空服务名,启动探针给慢启动镜像留出时间:
readinessProbe:
  exec:
    command: ["/bin/grpc_health_probe", "-addr=:50051", "-service=payments.v1.Payments"]
  periodSeconds: 10
  timeoutSeconds: 2
startupProbe:
  exec:
    command: ["/bin/grpc_health_probe", "-addr=:50051"]
  failureThreshold: 30
  periodSeconds: 2
  1. 本地用 grpcurl -plaintext localhost:50051 grpc.health.v1.Health/Check 手动确认返回值。
  2. 在 SIGTERM 处理逻辑中先把状态改为 NOT_SERVING,等待约 10 秒让调用方感知,再执行 GracefulStop()。

验证

预期 Health/Check 返回 {"status": "SERVING"}。发布时观察 Endpoints:Pod 应在进程退出前先变为未就绪并被摘除,滚动更新期间不应出现大量 UNAVAILABLE。若探针在启动阶段报连接拒绝,说明缺少启动探针或超时设置过短。

注意事项

  • 服务名字符串必须与注册时完全一致,否则探针收到 NOT_FOUND。
  • 健康状态需要业务代码主动维护,不会自动反映数据库故障;建议由后台检查更新缓存标志,避免每次探针都执行重查询。
  • 启用 TLS 时给探针增加 -tls 与服务名参数。
  • grpc-health-probe 需要额外复制进镜像,注意镜像体积与版本一致性。