Nginx 支持 gRPC 多路复用的前提是正确配置 HTTP/2 连接生命周期:启用 upstream keepalive(512~2000)、显式设置 keepalive_timeout(如 75s)、后端必须原生支持 H2C 或 TLS、禁用 grpc_buffering、设流级超时、客户端启用 round_robin 负载策略。

根本原因不是 Nginx “不支持”多路复用,而是配置未对齐 gRPC 的 HTTP/2 连接生命周期——Nginx 默认按 HTTP/1.x 短连接逻辑工作,若不显式启用并调优长连接池、禁用缓冲、匹配协议栈,gRPC 客户端建好的单个连接就无法被复用,导致每个 stream 都被迫新建后端连接,性能断崖式下降。
必须启用 upstream keepalive 并设合理容量
keepalive 不是可选优化,是支撑多路复用的基础设施。它让 Nginx worker 缓存与后端的空闲 HTTP/2 连接,供后续 stream 复用:
- 数值建议设为 256~2000(生产环境推荐从 512 起步),太小(如 4)会导致高并发下频繁建连、TIME_WAIT 泛滥;太大需确认系统 ulimit -n 是否足够
- keepalive_timeout 必须显式设置(如 75s),否则默认沿用 proxy_timeout(常为 60s),可能提前关闭空闲但活跃的流
- 指令必须写在 upstream 块末尾,且不能与 max_fails 等参数混行,语法错误会使整个 upstream 失效
后端服务必须原生支持 H2C 或明确启用 TLS
Nginx 与后端通信必须走真正的 HTTP/2,否则多路复用无从谈起:
- 若后端监听明文端口(如 :8080),必须原生支持 H2C(HTTP/2 without TLS),不能只支持 grpcs;否则 grpc_pass grpc:// 会握手失败
- 若后端强制 TLS(如双向认证),upstream 中必须用 grpcs:// 前缀,并配 grpc_ssl_verify off(测试)或完整证书链(生产)
- 禁止将 HTTP/1.1 服务混入同一 upstream——协议不匹配会导致部分 stream 静默失败
禁用缓冲 + 显式延长流级超时
HTTP/1.x 的缓冲和短超时机制会截断 gRPC 流帧,破坏多路复用基础:
- 必须设 grpc_buffering off:防止粘包、延迟或状态错乱,确保 DATA 帧实时透传
- 超时要按“流”而非“请求”粒度控制:grpc_read_timeout 3600 和 grpc_send_timeout 3600(单位秒),适应空闲流或大文件传输
- 避免使用 proxy_read_timeout / proxy_send_timeout 替代——它们作用于 HTTP/1.x 路径,对 grpc_pass 无效
客户端必须启用 round_robin 负载策略
Nginx 只管连接入口,真正决定 stream 分发的是 gRPC 客户端:
- Go 客户端默认 pick_first,DNS 解析出多个 IP 也只连第一个,其余节点闲置——这是 K8s Headless Service 下负载倾斜最常见根因
- 必须显式使用 dns:/// 前缀 dial,并传入 grpc.WithResolvers(dns.NewBuilder())
- 必须设置服务配置:grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin": {}}]}`)



















