关键在于打通系统级、服务级、nginx三级限制:先查清nginx用户ulimit及systemd limitnofile,再配/etc/security/limits.conf或systemd override.conf,接着在nginx.conf main块设worker_rlimit_nofile(≤hard nofile),events块设worker_connections(为该值的70%~85%),最后验证proc limits并观察error.log。

直接解决“Too many open files”报错,关键不是单改 Nginx 配置,而是打通系统级、服务级、Nginx 三级限制。worker_rlimit_nofile 本身只是“申请上限”,没有系统放行,它就形同虚设。
查清当前哪一级卡住了
别凭经验猜,按顺序验证真实限制值:
- 确认 Nginx 主进程运行用户:用 ps -eo pid,comm,user | grep nginx | grep master 查,常见为 www-data 或 nginx
- 查该用户的软硬限制:执行 sudo -u nginx bash -c "ulimit -Sn; ulimit -Hn"
- 查 systemd 服务限制(若用 systemd):运行 systemctl show nginx | grep LimitNOFILE
- 查正在运行的 worker 进程实际生效值:取一个 worker PID,执行 cat /proc/$(pgrep nginx | head -2 | tail -1)/limits | grep "Max open files"
同步放宽系统级文件句柄限制
根据部署方式选一种,必须做且只能选一种,不能混用:
- 若使用 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
这个指令必须放在 nginx.conf 最外层(main 上下文),即 events 块之前、http 块之外:
- 添加一行:worker_rlimit_nofile 65536;
- 该值必须 ≤ 系统为 nginx 用户设置的 hard nofile 值,建议设为 hard limit 的 90% 左右(如 hard 是 65536,这里设 59000~62000)
- 绝对不要写在 http 或 server 块里,否则不生效
合理设置 worker_connections 并验证
worker_connections 是每个 worker 实际能处理的并发连接数,它依赖于 worker_rlimit_nofile,但不能顶格用:
- events 块中设:worker_connections 50000;(建议为 worker_rlimit_nofile 的 70%~85%,预留 fd 给日志、上游连接、临时文件等)
- 重启后验证:执行 cat /proc/$(pgrep -f "nginx: worker")/limits | grep "Max open files",确认 Soft 和 Hard Limit 已更新为预期值
- 观察 error.log 是否还有 “Too many open files” 报错;高并发压测时检查连接是否稳定建立










