Nginx并发卡顿主因是文件描述符不足,而非worker_connections设置过低;必须同步调大ulimit -n、worker_rlimit_nofile和worker_connections三者,并验证proc limits与ss连接数。

这个错误不是连接池耗尽,也不是后端挂了,而是 Nginx 自身的并发连接能力被硬性卡住了。核心在于:每个 worker 进程能同时处理的连接总数,超出了它被允许打开的文件描述符(file descriptor, FD)上限。
错误本质是文件描述符不足
worker_connections 不是独立生效的数字。它代表“每个 worker 进程最多能建立多少个连接”,但每个连接(无论是客户端进来的,还是发给 upstream 的)都必须占用一个文件描述符。如果系统或进程级的 FD 限制比 worker_connections 小,Nginx 就会报这个错——哪怕你设了 30000,实际连 2000 都撑不住。
- Linux 默认每个进程最多打开 1024 个文件(ulimit -n 输出值),而 Nginx 默认 worker_connections 是 512 或 1024,刚好踩在临界点上
- 反向代理场景下,一个请求会消耗至少 2 个 FD:1 个连客户端,1 个连 upstream;若有临时文件、日志、缓存等,还会更多
- 错误日志里出现该提示,基本可以排除后端服务问题(重启后端无效,但 reload nginx 立刻恢复,就是典型信号)
三个关键配置必须协同调整
只改 worker_connections 是治标不治本。必须同步确认并设置以下三项:
- worker_rlimit_nofile:写在 main 上下文(即 http 块外),直接告诉 Nginx 进程能用多少 FD,建议设为与 ulimit -n 一致,例如 worker_rlimit_nofile 65535;
- worker_connections:写在 events 块内,建议设为 worker_rlimit_nofile / 2 左右(留出空间给日志、临时文件等),常见值 10240、30000、65535
- ulimit -n:系统级限制,需永久修改 /etc/security/limits.conf(soft/hard nofile),改完需重新登录或重启 systemd 服务才生效
检查和验证的实操步骤
别猜,用命令逐层确认:
- 查当前系统限制:ulimit -n(看输出是否 ≥ 65535)
- 查 Nginx 运行时限制:cat /proc/$(pgrep nginx)/limits | grep "Max open files"(确认 soft 和 hard 值)
- 查配置是否加载:nginx -t 检查语法,nginx -s reload 生效(不要 kill -HUP)
- 查实时连接数:ss -s | grep "TCP:" 或 netstat -an | wc -l(粗略估算并发压力)
物理机与容器环境的差异提醒
物理服务器资源充足时,可大胆调高数值(如 worker_connections 300000);但在 Docker/K8s/Rancher 等容器环境中,需额外注意:
- 容器默认继承宿主机的 ulimit,但部分编排平台(如旧版 Rancher)可能未透传,需在 deployment 中显式设置 ulimits
- Kubernetes 中应通过 securityContext 设置 ulimits,否则即使 Nginx 配置正确,也会被容器运行时截断
- 云环境(如腾讯云、阿里云)某些镜像自带精简版 Nginx,可能需要换用官方完整版二进制











