nginx反向代理下单worker最大并发请求数≈worker_connections/2,因每个请求需占用2个fd(客户端+后端各1个),且受系统ulimit、内存、upstream连接池等多重约束。

在 Nginx 反向代理模式下,单个 worker 进程的**最大并发连接数并不是直接等于 worker_connections 的值,而是通常要除以 2**。原因在于:每个客户端请求在反向代理场景中会占用**两个文件描述符(FD)**——一个用于与客户端建立连接,另一个用于与后端服务器(upstream)建立连接。
为什么是除以 2?
Nginx 在反向代理时采用“双边连接”模型:
- 前端:接收并维持一个 TCP 连接到客户端(如浏览器);
- 后端:主动发起并维持一个 TCP 连接到上游服务(如 Flask、Tomcat、Node.js 等)。
这两个连接独立存在、生命周期可能不同(例如启用 keepalive 时前端连接可复用,后端连接可能短连),但**在请求处理期间必须同时打开**。因此,每个活跃的代理请求至少消耗 2 个文件描述符。
而 worker_connections 配置项限制的是该 worker 进程**最多能同时打开的文件描述符总数**(包括监听 socket、客户端连接、上游连接、缓存文件句柄等)。在高并发代理场景下,连接类 FD 占主导,所以保守估算时,可用并发请求数 ≈ worker_connections / 2。
实际能支撑多少并发?还要看这些限制
除以 2 是理论下限估算,真实并发能力还受以下因素制约:
-
系统级文件描述符限制:通过
ulimit -n查看,需 ≥worker_processes × worker_connections × 1.2(留余量); -
上游连接池配置:若未配置
keepalive,每次请求都新建后端连接,FD 消耗更快、延迟更高;合理设置keepalive 32并配合proxy_http_version 1.1和Connection ''可复用后端连接,缓解压力; - 内存与 CPU:每个连接约占用几 KB 内存(buffer、ssl session 等),高并发下内存易成瓶颈;worker 过多反而因上下文切换降低性能;
-
TIME_WAIT 连接堆积:若 Nginx 主动关闭后端连接(如 upstream 响应快、Nginx 提前断连),大量 TIME_WAIT 会占用本地端口和 FD,需调优
net.ipv4.ip_local_port_range和net.ipv4.tcp_fin_timeout。
怎么验证当前 worker 的实际连接占用?
可通过以下方式观察运行时状态:
- 查活跃连接数:
ss -s | grep "tcp:"或netstat -an | grep :80 | wc -l(粗略); - 查 Nginx 内部统计:
curl http://127.0.0.1/nginx_status(需开启ngx_http_stub_status_module),关注Active connections; - 查 worker 打开的 FD 数:
lsof -p $(cat /var/run/nginx.pid) | wc -l,对比worker_connections是否接近上限。
优化建议:让单 worker 支撑更多有效并发
- 启用 upstream keepalive:减少后端建连开销,降低 FD 峰值占用;
- 调大
worker_rlimit_nofile,确保 worker 能突破系统默认 ulimit; - 使用
epoll(Linux 默认)+accept_mutex on(旧版本需显式开,新版本默认优化); - 避免在 proxy 中开启不必要的 buffer(如
proxy_buffering off适合流式响应),减少内存/FD 关联开销; - 监控
nginx stub_status中的Reading/Writing/Waiting分布,Waiting 高说明请求处理快、连接空闲多,可适当调高并发预期。
不复杂但容易忽略:除以 2 不是硬性公式,而是理解双边连接本质后的经验基准。真正压测时,应以 lsof + stub_status + 后端响应时间三者结合判断瓶颈所在。











