直接检查nginx是否被fd卡住:查/proc/sys/fs/file-nr第二列是否近第三列、lsof -p $(pidof nginx) | wc -l对比/proc/$(pidof nginx)/limits中max open files值,再比对fs.file-max、ulimit -n及进程实际值,任一为1024即瓶颈。

直接看 Nginx 是否被文件描述符(FD)卡住,而不是先怀疑代码或后端。高并发下“Too many open files”不是偶然报错,是资源硬上限被击穿的明确信号。
确认是否真耗尽
别只看错误日志,要量化验证:
- 查系统全局 FD 使用:运行
cat /proc/sys/fs/file-nr,重点关注第二列(已分配未释放的 FD 数),如果接近第三列(最大值),说明系统级快满 - 查 Nginx 进程当前打开数:
lsof -p $(cat /var/run/nginx.pid) | wc -l,再对比它的限制:cat /proc/$(cat /var/run/nginx.pid)/limits | grep "Max open files" - 对比三组数值:系统最大(
fs.file-max)、用户软限(ulimit -n)、Nginx 进程实际生效值——只要其中任意一个明显偏低(比如只有 1024),就是瓶颈所在
定位谁在占、占什么
Nginx 自身 FD 消耗有规律,重点查这几类:
PyCharm 2026.2.0.1 Linux版提供 JetBrains 官方 2026.2.0.1 版本安装包,适合需要指定 PyCharm 版本进行 Python 项目开发、运行和调试的用户。
- 每个客户端连接占 1 个 FD,每个 upstream 连接也占 1 个,反向代理场景下 1 个请求至少消耗 2 个 FD
- 运行
lsof -p $(cat /var/run/nginx.pid) | awk '{print $5}' | sort | uniq -c | sort -nr,看最多的是IPv4、IPv6(连接)、REG(静态文件)、PIPE或eventpoll(epoll 实例) - 若发现大量
socket处于ESTABLISHED但长时间不关闭,可能是 client_body_timeout、keepalive_timeout 设置过长,或客户端异常断连未触发回收
检查配置是否真正生效
很多问题出在“设了但没生效”:
-
worker_rlimit_nofile必须显式写在 nginx.conf 的 main 块里,且值 ≥worker_connections -
/etc/security/limits.conf修改后,systemd 管理的服务默认不继承,必须在 service 文件里加LimitNOFILE=65535 - 改完 limits.conf 后,要重启登录会话或用
sudo systemctl daemon-reload && sudo systemctl restart nginx才能刷新进程限制 - 临时用
ulimit -n 65535启动 nginx 不生效——systemd 会覆盖 shell 的 ulimit
验证与收口
调完不能只等下次出事,要主动压测验证:
- 用
ab或wrk模拟并发连接,观察ss -s输出的total和tcp行变化,同时监控/proc/$(cat /var/run/nginx.pid)/fd/目录数量增长是否平滑 - 错误日志里不再出现
accept() failed (24: Too many open files),且worker process XXX exited on signal 9消失 - 长期建议加监控项:Nginx 的
ngx_http_stub_status_module中的 Active connections,配合cat /proc/$(pidof nginx)/fd | wc -l做趋势告警










