看到 accept() failed (24: Too many open files) 即可确认是文件描述符(FD)耗尽导致连接拒绝,需立即分层排查:若仅个别 worker 频繁报错,可能 FD 泄漏;若所有 worker 同步密集报错,则系统级 file-max 告急;三层数值(系统、用户、进程)任一为 1024 即为瓶颈,必须对齐调优。

看到 accept() failed (24: Too many open files),基本可以确定是文件描述符(FD)耗尽导致连接被拒绝。这不是偶发报错,而是系统资源硬上限被击穿的明确信号——别绕弯子查后端或网络,先聚焦 FD。
盯紧 error_log 里的关键错误
这条日志是第一手证据,但需结合频率和上下文判断:
- 单个 worker 频繁报错(如 PID 12345、67890),其他 worker 正常 → 可能该 worker 存在 FD 泄漏(比如长连接堆积、upstream 连接未释放)
- 所有 worker 在同一分钟内密集报错 → 更可能是系统级 FD 总量告急,要立刻查 dmesg | grep -i "file-max"
- 同时出现 worker_connections are not enough → 说明 FD 不足已传导到连接层,worker 即使有槽位也拿不到 fd
三层数值必须对齐,缺一不可
Nginx 能用多少 FD,取决于三个地方的最小值。任一为 1024 就是瓶颈:
-
系统全局上限:运行
cat /proc/sys/fs/file-max,建议设为 ≥1000000 -
用户级限制:运行
ulimit -n,若输出 1024,说明 limits.conf 没生效或未重启会话 -
Nginx 进程实际值:运行
cat /proc/$(cat /var/run/nginx.pid)/limits | grep "Max open files",确认是否等于你设的worker_rlimit_nofile
看进程到底开了多少 FD,不是猜
别只看配置,要量化验证:
- 查 Nginx 主进程当前打开数:
ls -l /proc/$(cat /var/run/nginx.pid)/fd/ 2>/dev/null | wc -l,正常几百到一两千;持续过万就危险 - 查某个 worker 进程(取第一个):
lsof -p $(pgrep nginx | head -1) | wc -l,再对比它的Max open files值 - 看系统整体使用率:
cat /proc/sys/fs/file-nr,重点看第一列(已分配总数)是否 ≥ 第三列(file-max)的 90%
定位谁在占、占的是什么
FD 耗尽不一定是 Nginx 自己的问题,也可能是其他进程吃光了资源:
- 找系统里 FD 占用 Top 10:
lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | head -10 - 对可疑 PID,看它开得最多的是啥:
lsof -p PID | awk '{print $5}' | sort | uniq -c | sort -nr - 重点关注:大量 IPv4/IPv6(连接未及时关闭)、REG(静态文件未释放)、anon_inode(eventfd/timerfd 泄漏)


















