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

看到 accept() failed (24: Too many open files) 这条日志,基本可以确认是文件描述符(FD)耗尽导致 Nginx 无法接受新连接。这不是配置错误或网络问题,而是系统资源被硬性打穿的明确信号——必须分层验证、逐级对齐,不能只改一处。
盯住 error_log 里的关键线索
这条错误本身不说明“在哪一层”耗尽,但报错模式能快速定位方向:
- 仅个别 worker 进程(如 PID 12345、67890)反复报错,其他 worker 正常 → 很可能是该 worker 存在 FD 泄漏(比如 upstream 连接未释放、长连接堆积、模块异常)
- 所有 worker 在同一分钟内密集报错 → 更可能是系统级 file-max 告急,需立刻查内核限制
- 同时出现 worker_connections are not enough 提示 → 说明 FD 不足已传导到连接层,worker 即使有空槽也拿不到 fd
检查三层 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%
定位泄漏源和高消耗类型
系统级告警下,往往是个别进程“吃光”了资源:
- 用 lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | head -10 找出 FD 占用 Top 10 的 PID
- 对可疑 PID,执行 lsof -p
| awk '{print $5}' | sort | uniq -c | sort -nr 看它主要在开什么:大量 IPv4/IPv6 表示连接未及时关闭;大量 anon_inode 可能是 eventfd/timerfd 泄漏;大量 pipe 或 inotify 则指向模块或脚本逻辑问题 - 特别注意:
worker_connections和worker_rlimit_nofile必须匹配,且满足公式:worker_rlimit_nofile ≥ worker_connections × worker_processes











