解决nginx句柄耗尽需系统、systemd、nginx三层限制对齐:先定位瓶颈层,再同步调大ulimit、limitnofile和worker_rlimit_nofile,并关联优化worker_connections与内核参数。

要解决负载均衡场景下 Nginx 因句柄耗尽导致的 502 Bad Gateway 或 open() failed (24: Too many open files) 错误,关键不是单独调大某个参数,而是让系统、服务管理器、Nginx 三层限制对齐并留有余量。
确认当前瓶颈在哪一层
别凭经验猜,先查真实值:
- 看 Nginx 主进程运行用户:
ps -eo pid,comm,user | grep nginx | grep master(常见为nginx或www-data) - 查该用户的软硬限制:
sudo -u nginx bash -c "ulimit -Sn; ulimit -Hn" - 查 systemd 是否覆盖限制:
systemctl show nginx | grep LimitNOFILE - 查 worker 进程实际生效值:
cat /proc/$(pgrep nginx | head -2 | tail -1)/limits | grep "Max open files"
同步调整系统级 nofile 限制
根据你的启动方式选一种,必须做,不能跳过:
- 若用 systemd(主流发行版默认):新建或编辑
/etc/systemd/system/nginx.service.d/override.conf,写入
[Service]
LimitNOFILE=65536
然后执行:sudo systemctl daemon-reload && sudo systemctl restart nginx - 若用传统方式或手动启停:编辑
/etc/security/limits.conf,添加两行(用户名需匹配):
nginx soft nofile 65536
nginx hard nofile 65536
并确认/etc/pam.d/common-session中有session required pam_limits.so
正确配置 Nginx 的 worker_rlimit_nofile
这个指令只在 main 上下文生效,位置很关键:
- 打开
nginx.conf,在events块之前、http块之外的最外层添加:
worker_rlimit_nofile 65536; - 数值必须 ≤ 系统为 nginx 用户设置的 hard nofile 值(即上一步中
ulimit -Hn的输出),建议设为硬限制的 90% 左右,留出空间给日志、临时文件等 - 不能写在
http、server或location块内,否则 Nginx 启动报错:“unknown directive”
关联调优 worker_connections 和内核参数
worker_rlimit_nofile 是底座,但不是全部:
-
worker_connections应设为worker_rlimit_nofile的 70%~90%,例如设worker_rlimit_nofile 65536,则worker_connections可设为50000;过高会导致连接建立失败 - 检查并调优内核参数:
net.core.somaxconn(建议 ≥ 65535)、net.ipv4.ip_local_port_range(建议1024 65535)、fs.file-max(建议 ≥ 2097152) - 重启后务必验证:
cat /proc/$(pgrep nginx | head -2 | tail -1)/limits | grep "Max open files",Soft Limit 应等于你设的值










