nginx高并发下文件句柄耗尽需同步调优四层限制:系统级(fs.file-max)、用户级(limits.conf)、systemd级(limitnofile)、nginx进程级(worker_rlimit_nofile),并合理配置worker_connections、关闭冗余日志、启用upstream keepalive及open_file_cache。

Nginx 高并发下文件句柄耗尽,本质是系统资源分配与 Nginx 运行模型没对齐,不是简单调大一个参数就能解决。关键在于四层限制必须同步到位,且每层留出合理余量。
确认瓶颈在哪一层
先别改配置,用几条命令快速定位:
- 查系统总上限:
cat /proc/sys/fs/file-max(建议 ≥ 2097152) - 查 nginx 用户当前软硬限制:
sudo -u nginx bash -c "ulimit -Sn; ulimit -Hn"(默认常为 1024,明显不够) - 查 systemd 是否覆盖:
systemctl show nginx | grep LimitNOFILE - 查 worker 进程真实生效值:
cat /proc/$(pgrep nginx | head -2 | tail -1)/limits | grep "Max open files"
如果这四个值不一致,或者任意一层低于 65536,就一定会出 accept() failed (24: Too many open files) 或 socket() failed 错误。
同步调高四层限制
缺一不可,顺序不能乱:
系统级:编辑
/etc/sysctl.conf,加一行fs.file-max = 2097152
执行sysctl -p用户级:编辑
/etc/security/limits.conf,按实际运行用户(如nginx或www-data)添加
nginx soft nofile 65536
nginx hard nofile 65536-
systemd 级(主流发行版必做):
创建/etc/systemd/system/nginx.service.d/override.conf,内容为[Service] LimitNOFILE=65536
然后执行
systemctl daemon-reload && systemctl restart nginx Nginx 进程级:在
nginx.conf最外层(events块之前、http块之外)添加
worker_rlimit_nofile 60000;
(注意:数值 ≤ hard nofile,建议取 90% 左右,留空间给日志、SSL 缓存等)
合理设置 worker_connections 和进程数
-
worker_processes auto;(自动匹配 CPU 核心数,不建议盲目设高) -
events { worker_connections 50000; }(建议为worker_rlimit_nofile的 70%~85%) - 每个活跃连接至少占 1 个 fd;HTTPS、代理场景中,上游连接、SSL session、OCSP stapling 等会额外消耗,务必预留
减少非必要句柄占用
- 关闭未使用的 access_log:
access_log off;或启用 buffer+flush - 启用 upstream keepalive:在
upstream块中加keepalive 32;,避免每个请求新建后端连接 - 静态资源服务可开启
open_file_cache,缓存元信息和 fd 复用,降低重复 open/close - 检查是否启用了过多模块(如
ngx_http_perl_module)或调试日志,它们也会悄悄吃掉句柄
调完之后,用 lsof -p $(pgrep nginx) | wc -l 对比前后变化,并持续观察 error.log 是否还有 Too many open files 报错。真正稳定的高并发,靠的是资源协同,不是堆数字。











