Golang服务健康检查应暴露轻量探活端点,HTTP适用于多数场景(如K8s、Nginx),gRPC适合内部强契约通信;需避免耗时操作、引入状态缓存、分离Liveness/Readiness逻辑。
用 Golang 做服务健康检查,核心是暴露一个轻量、可靠、低开销的探活端点,并让外部(如 K8s、Consul、Nginx 或自建巡检系统)能定期调用它。HTTP 和 gRPC 各有适用场景:H
TTP 简单通用,适合大多数基础设施集成;gRPC 更适合内部微服务间强契约、低延迟的健康通信,但需客户端支持。
HTTP 方式最常用,Kubernetes Liveness/Readiness、Nginx upstream health check、Prometheus blackbox exporter 都原生支持。关键是要返回明确状态码 + 可读响应体。
/healthz(或 /health)端点,返回 200 OK 表示存活,非 200(如 503)表示异常{"status":"ok","checks":{"db":"ok","redis":"ok"}},但不要影响状态码逻辑ReadTimeout、WriteTimeout,防止健康接口被阻塞拖垮整个服务如果你的服务已全面采用 gRPC,且调用方也是 gRPC 客户端(如 Istio、gRPC-Go 客户端),可用官方 gRPC Health Checking Protocol,它定义了标准的 HealthCheckService 接口。
google.golang.org/grpc/health 和 google.golang.org/grpc/health/grpc_health_v1
health.Server 实例,调用 SetServingStatus 主动上报服务状态(servicename 为空字符串表示默认服务)grpc_health_v1.RegisterHealthServer(grpcServer, healthServer)
grpc_health_v1.NewHealthClient(conn).Check(ctx, &grpc_health_v1.HealthCheckRequest{Service: ""}) 发起探活,成功且 status == SERVING 即为健康SetServingStatus 前同步执行轻量检查(如检查数据库连接是否有效)频繁的探活请求(尤其高并发时)若每次都实时检查 DB/Redis,会带来不必要压力。更优做法是后台 goroutine 定期执行真实检查,把结果缓存在内存中,探活端点只读取快照。
time.Ticker 每 5–10 秒执行一次依赖检查(如 db.PingContext())type HealthStatus struct { DBOK, RedisOK bool }),保证并发安全读写K8s 中 livenessProbe 决定是否重启容器,readinessProbe 决定是否加入 Service Endpoint。二者逻辑应不同:
/healthz/liveness vs /healthz/readiness)基本上就这些。HTTP 适合绝大多数场景,开箱即用;gRPC 健康检查适合深度 gRPC 架构;加上状态缓存和 K8s 探针分离,就能支撑生产级稳定性要求。不复杂但容易忽略细节——关键是别让健康检查本身成为故障源。