必须先在systemd中设置limitnofile,再在nginx.conf顶层配置worker_rlimit_nofile;前者是前提,后者是应用,两者需协同并留余量,否则无法突破文件句柄瓶颈。

直接在 Nginx 配置里写 worker_rlimit_nofile 不会突破瓶颈,它只是“申请”更多句柄,真正起作用的是 systemd 服务层的限制。必须先放开 systemd 的 LimitNOFILE,Nginx 才能成功调用 setrlimit() 设置更高的软限制。
先确认 nginx 运行用户和当前限制
执行以下命令,明确实际运行身份和系统当前给它的上限:
-
ps -eo pid,comm,user | grep nginx | grep master→ 查出用户(如nginx或www-data) -
sudo -u nginx bash -c "ulimit -Sn; ulimit -Hn"→ 查该用户的软/硬限制值 -
systemctl show nginx | grep LimitNOFILE→ 看 systemd 是否已设限(默认常为 1024)
在 systemd 中覆盖 LimitNOFILE
这是最关键的一步。创建覆盖配置文件,让 systemd 启动 nginx 时分配足够句柄:
- 新建目录与文件:
sudo mkdir -p /etc/systemd/system/nginx.service.d - 写入:
sudo tee /etc/systemd/system/nginx.service.d/override.conf,内容为:
[Service] LimitNOFILE=1048576
- 重载并重启:
sudo systemctl daemon-reload && sudo systemctl restart nginx
注意:不能只改 /etc/security/limits.conf,systemd 默认忽略它;也不能只设软限制,LimitNOFILE 同时控制软硬限。
在 nginx.conf main 上下文中设置 worker_rlimit_nofile
这个指令必须放在最外层,即 events 和 http 块之外、之前:
- 打开
/etc/nginx/nginx.conf,在worker_processes下方、events { ... }上方添加一行:
worker_rlimit_nofile 943718;
- 数值建议为
LimitNOFILE值的 90% 左右(如上例 1048576 × 0.9 ≈ 943718),留出余量给日志、SSL 缓存、临时文件等 - 切勿写在
http、server或location块内,否则启动报错或静默忽略
配套验证与关联调优
配置生效≠真正可用,需验证+协同:
- 查 worker 进程真实值:
cat /proc/$(pgrep -f "nginx: worker" | head -n1)/limits | grep "Max open files"→ Soft Limit 应等于你设的worker_rlimit_nofile - 匹配
worker_connections:在events块中设为worker_rlimit_nofile的 70%~85%,例如:worker_connections 700000; - 确保内核参数支撑:检查
fs.file-max是否足够(建议 ≥ 2× 总句柄需求),必要时写入/etc/sysctl.conf并执行sysctl -p











