nginx连接拒绝的根本原因是worker进程连接槽位耗尽,需同步调优系统级、进程级、内核级三层文件描述符限制,并合理配置worker_connections、事件模型及反向代理资源占用。

这个错误不是配置没写对,而是 Nginx 已经“排队排到门外”了——单个 worker 进程的连接槽位被占满,新连接进不来。它常表现为 502、504、连接拒绝或响应变慢,但后端可能完全健康。关键不在加机器,而在理清三层限制是否对齐。
先确认是不是真卡在这里
别一看到报错就改配置。先快速验证瓶颈是否属实:
- 查当前活跃连接:
ss -s | grep "TCP:"或netstat -ant | grep ESTABLISHED | wc -l,对比worker_processes × worker_connections是否接近满载 - 翻错误日志:
grep "worker_connections" /var/log/nginx/error.log,重点看有没有accept() failed (24: Too many open files)或明确提示are more than open file resource limit - 查系统限制:
ulimit -n(当前用户软限制)、cat /proc/sys/fs/file-max(系统总上限)、cat /proc/$(pgrep nginx)/limits | grep "Max open files"(Nginx 进程实际拿到的 fd 上限)
必须同步调的三项底层限制
只改 worker_connections 是无效的。它像汽车的油表,而真实油量由三道阀门控制:系统级、进程级、内核级。
-
系统级文件描述符:编辑
/etc/security/limits.conf,追加两行(把nginx换成你实际运行用户,如www-data):nginx soft nofile 65535nginx hard nofile 65535
若用 systemd 启动,还需在/etc/systemd/system/nginx.service的[Service]下加LimitNOFILE=65535,再执行systemctl daemon-reload -
Nginx 进程级声明:在
nginx.conf的 main 块(events外、http上方)添加:worker_rlimit_nofile 65535;
该值必须 ≥ 单个worker_connections,建议设为相同数值 -
内核连接队列深度:编辑
/etc/sysctl.conf,加入:net.core.somaxconn = 65535net.core.netdev_max_backlog = 25000
执行sysctl -p生效。这个参数管的是“还没进 Nginx 的排队区”,不调大会丢 SYN 包
合理设置 worker_connections 数值
不是越大越好,要结合业务类型和硬件资源:
- 普通网站或中低频 API:
worker_connections 4096~8192已足够 - 高频短连接(如压测、移动端接口):
16384~32768,并建议keepalive_timeout 0彻底禁用长连接 - 长连接场景(WebSocket、HTTP/2):
8192~16384更稳妥,配合keepalive_timeout 15–30s加速释放 - 内存估算:每个连接约占 2–4 KB。8 GB 内存服务器,单 worker 不建议超
65535;16 GB 可考虑131072,但需同步提升fs.file-max
配套 events 块优化不可少
光改数字不够,还要让事件模型高效运转:
- 显式声明:
use epoll;(Linux 必须,避免回退到 select/poll) - 提升突发处理能力:
multi_accept on;(一次事件循环多收几个连接) - 高并发下可尝试:
accept_mutex off;(减少锁争抢,尤其搭配reuseport时效果明显) - 反向代理务必注意:每个客户端连接 + 每个 upstream 连接都占用一个
worker_connections槽位,实际可用约为理论值的 70%~80%
改完务必执行 nginx -t 验证语法,再用 nginx -s reload 平滑重载。观察几小时错误日志,确认不再出现相关告警。整个过程不复杂,但容易忽略其中一环导致白调。











