一个grpc双向流只计1个worker_connections,因为其基于http/2多路复用,单个tcp连接承载多个stream id的数据帧,nginx将其视为一个文件描述符;反向代理时因需维护客户端和上游两个连接,实际消耗2个配额。

gRPC 双向流式传输(Bidi Streaming)在 Nginx 中属于长连接、高保活、单连接多路复用的典型场景,worker_connections 不是按请求数算,而是按活跃 TCP 连接数算——每个 gRPC 流式连接只占 1 个 worker_connections 配额,无论它内部承载多少次 request/response 交换。
为什么一个 gRPC 流只计 1 个连接
gRPC 默认基于 HTTP/2,而 HTTP/2 天然支持多路复用(multiplexing)。Nginx(1.19.10+ 启用 http_v2 模块)将整个 TCP 连接视为一个文件描述符(fd),后续所有 stream ID 的数据帧都在该连接内并发收发。因此:
- 客户端建立 1 个 TLS 握手的 TCP 连接 → 占用 1 个 worker_connections
- 在此连接上发起 5 个独立的 bidi-stream RPC → 仍只占用这 1 个连接,不新增 fd
- 连接断开或超时(如 keepalive_timeout 触发)后,才释放该计数
反向代理场景下的实际连接开销
当 Nginx 作为 gRPC 反向代理(proxy_pass 到上游 gRPC 服务)时,需同时维护两个连接:
- 1 个面向客户端的 HTTP/2 连接(计入 worker_connections)
- 1 个面向 upstream 的 HTTP/2 连接(也计入同一 worker 进程的 worker_connections)
即:1 个客户端 gRPC 流 → 消耗 2 个并发连接配额(client + upstream 各 1)。这是反向代理模式下连接数翻倍的关键原因,不是“请求翻倍”,而是“连接对翻倍”。
配置建议与容量校验要点
针对 gRPC Bidi 流,worker_connections 应侧重稳定性与连接驻留时间,而非短连接吞吐量:
- 设为 2048–8192(避免过高导致内存压力;每个 HTTP/2 连接平均内存开销约 150–300 KB)
- 必须启用 keepalive:在 upstream 块中配置 keepalive 32;(复用到后端的连接池)
- 调高 keepalive_timeout(如 60–180 秒),防止流式连接被过早中断
- 确保 ulimit -n ≥ 2 × worker_connections × worker_processes(因双连接模型)
- 检查运行时:访问
/nginx_status,观察 Active connections 是否长期 >85% 配置值;若 Waiting 占比极高(>95%),说明大量空闲流挂起,需关注 fd 和内存是否充足
别忽略的底层约束
即使配置合理,gRPC 流式连接仍受三重限制共同制约:
- 进程级:每个 worker 进程的 ulimit -n 必须 ≥ 2 × worker_connections
- Nginx 级:worker_rlimit_nofile ≥ worker_processes × 2 × worker_connections
- 系统级:/proc/sys/fs/file-max ≥ 1.5 × (worker_processes × 2 × worker_connections)
任一环节不足,都会出现 accept() failed (24: Too many open files) 或流式连接随机中断。











