gRPC 生产落地:从 ClusterIP 长连接倾斜到 Headless DNS、Envoy 与全链路治理
gRPC 在 Kubernetes 中“能调用成功”并不等于“已经具备生产级负载均衡”。当客户端只解析到一个 ClusterIP,再通过一条长期存在的 HTTP/2 连接发送请求时,多个 Pod 很可能长期冷热不均。
本文以 service-a 这一通用 Java 服务为例,复盘一条典型的生产治理路径:保留现有 ClusterIP Service 兼容原有调用,再增加只供内部 gRPC 发现的 Headless Service,让 Java gRPC 客户端和 Envoy 看见每一个 Pod,并把服务发现、健康检查、摘流、连接排空、超时重试、可观测性和发布验收串成闭环。
如果需要先补齐协议和 Java 基础,可以依次阅读 HTTP/2 协议层、Java 与 Netty 实现 和 gRPC 生产治理;本文专注 Kubernetes 与 Envoy 的端点级落地。
这不是一份只解决“DNS 返回几个 IP”的配置说明。生产落地需要同时回答六个问题:
- 客户端究竟发现了 VIP,还是每个 Pod?
- 负载均衡发生在 TCP 连接、HTTP/2 Stream,还是 RPC 级别?
- 不可用 Pod 会不会继续出现在发现结果里?
- Pod 下线时,存量长连接和在途 RPC 如何处理?
- Java 客户端与 Envoy 谁负责重试、健康检查和摘除?
- 如何证明流量真的分散,而不是只证明 DNS 能解析?