nginx拒绝新连接且日志频繁出现“accept() failed (24: too many open files)”表明文件描述符耗尽,需同步调优系统fs.file-max、用户limits.conf、systemd limitnofile及nginx.conf中worker_rlimit_nofile与worker_connections四层限制。

当 Nginx 拒绝新连接(如返回 502、503,或客户端报错 Connection refused / Connection reset),且日志中频繁出现 accept() failed (24: Too many open files) 或 epoll_ctl() failed (24: Too many open files),大概率是 worker_connections 耗尽或其依赖的系统级资源不足。排查需从 Nginx 配置、内核限制、运行时状态三方面交叉验证。
确认当前 worker_connections 实际生效值
Nginx 实际可用连接数 = worker_processes × worker_connections,但该值受系统 ulimit -n 严格限制。即使配置了 worker_connections 10240,若单个 worker 进程最大可打开文件数只有 1024,真实上限仍是 worker_processes × 1024。
- 检查主配置:
grep -E "worker_processes|worker_connections" /etc/nginx/nginx.conf - 确认生效值:执行
nginx -T 2>/dev/null | grep -E "worker_processes|worker_connections"(-T输出完整生效配置,含 include) - 注意:若
worker_processes auto,实际进程数等于 CPU 核心数,需一并计入计算
检查系统级文件描述符限制
Nginx worker 进程能打开的连接数不能超过其 soft limit(软限制)。该限制由启动用户决定,与 root 启动后降权有关。
- 查 Nginx 主进程用户:
ps -eo pid,user,comm | grep nginx | grep master - 查该用户下任意 worker 进程的 limits:
cat /proc/$(pgrep -f "nginx: worker")/limits | grep "Max open files" - 常见问题:systemd 启动时未覆盖默认限制。需在
/etc/systemd/system/nginx.service.d/override.conf中添加:[Service]<br>LimitNOFILE=65536
然后执行systemctl daemon-reload && systemctl restart nginx
观察实时连接与句柄占用情况
光看配置不够,要验证运行时是否真“满”了。
- 统计当前所有 worker 进程打开的 socket 连接数:
ss -s | grep "tcp:"(看 total established + synrecv 等),或更精准:lsof -p $(pgrep -f "nginx: worker") | grep sock | wc -l - 查看 Nginx 自带连接监控(需启用 stub_status):
在 server 块中配置location /nginx_status { stub_status; allow 127.0.0.1; deny all; },然后请求curl http://127.0.0.1/nginx_status。
关注输出中的Active connections:—— 这是当前活跃连接数;server accepts handled requests三元组中,若accepts ≠ handled,说明有连接被接受后未能处理完就断开(可能因超时或上游阻塞),但更关键的是看accepts是否持续增长而handled滞后,暗示连接堆积 - 检查错误日志高频关键词:
tail -f /var/log/nginx/error.log | grep -i "too many open files\|accept() failed\|epoll_ctl() failed"
区分是连接数瓶颈还是其他资源瓶颈
现象相似,但原因不同。需排除干扰:
-
TIME_WAIT 过多:短连接高频场景下,大量 socket 停留在 TIME_WAIT 占用端口和 fd。检查:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}',若TIME_WAIT超过 2~3 万,需调优net.ipv4.tcp_tw_reuse和net.ipv4.ip_local_port_range -
上游服务拖慢:Nginx 与后端(如 PHP-FPM、Upstream)连接未及时释放,导致 worker 连接被长期占用。检查 upstream 的
keepalive设置、后端响应时间、超时参数(proxy_read_timeout等) -
客户端长连接未复用:HTTP/1.0 或未设
Connection: keep-alive,导致每个请求建新连接。可通过$connection_requests变量(在 access_log 中记录)分析平均每个连接处理请求数,偏低则说明复用率差











