关键在于正确配置nginx的upstream+grpc_pass组合、调优超时与缓冲参数(如grpc_read_timeout 300s)、使用least_conn负载算法、禁用ip_hash,并启用ssl卸载与健康检查,以保障grpc双向流稳定不中断。

直接用 grpc_pass 做 gRPC 代理并实现负载均衡,关键不在“能不能”,而在“怎么配才不掉流、不超时、不乱分发”。Nginx 自 1.13.10 起原生支持 gRPC(基于 HTTP/2),但默认 HTTP 配置几乎全部不适用——尤其是双向流场景。下面聚焦最常用、最易出错的几个实操要点。
必须用 upstream + grpc_pass 组合
不能像 HTTP 那样直接写 proxy_pass http://10.0.1.10:11800。gRPC 必须走 upstream 定义后端组,再由 grpc_pass 引用:
-
upstream块里定义多个 OAP 实例,比如 Skywalking 后端集群 -
server块中监听 443 或 80(推荐 443 + TLS),location 匹配 gRPC 路径(通常为/) - 在 location 内使用
grpc_pass grpc://oap_cluster(明文)或grpc_pass grpcs://oap_cluster(加密) - 注意:
grpc://前缀可省略,但grpcs://不可省,否则会降级为明文
双向流必须调优 timeout 和 buffer
gRPC 双向流可能持续数分钟甚至更久,Nginx 默认超时(60s)会直接中断连接。Skywalking Agent 的心跳和持续上报就依赖稳定长连接:
-
grpc_connect_timeout 10s:建立初始连接允许耗时 -
grpc_send_timeout 300s:客户端两次发数据的最大间隔(如心跳 45s,建议 ≥60s) -
grpc_read_timeout 300s:服务端响应或推送流数据的最大空闲时间 -
grpc_buffer_size 128k:避免大 trace 数据被截断;若启用了采样或大 span,可设为 256k -
reset_timedout_connection off:务必关闭!否则 Nginx 会主动 kill “看似空闲”的活跃流
选 least_conn,别用 ip_hash
gRPC 客户端(如 Java Agent)普遍复用连接池,一个进程可能只建几个长连接并发大量 stream。IP 哈希会导致所有 stream 扎堆到同一台后端:
- 用
least_conn算法,按当前活跃连接数分发,更适合流式负载 - 配合健康检查:
max_fails=3 fail_timeout=30s,快速剔除故障节点 - 加
keepalive 32:每个 worker 复用最多 32 个空闲连接,降低 TLS 握手与 TCP 建连开销 - 禁用
ip_hash、hash $remote_addr类指令,除非你明确需要会话粘性且已确认客户端连接行为可控
TLS 终止与证书管理要点
生产环境必须启用 HTTPS + HTTP/2,否则客户端(尤其 Go/Python)会拒绝连接:
- Nginx 层做 SSL 卸载(SSL offloading)最常见:前端用
ssl_certificate+ssl_certificate_key,后端仍走明文grpc:// - 证书需由可信 CA 签发;自签名仅限测试,且客户端必须显式跳过校验(不推荐)
- Ingress 场景下,通过
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"注解启用 HTTP/2 代理 - 确保 nginx 编译时启用了
--with-http_v2_module和--with-http_ssl_module











