调高 worker_rlimit_nofile 是解决 Nginx “too many open files” 错误的关键,但必须同步调整系统级 file-max、用户 limits.conf 及 systemd LimitNOFILE,并确保其 ≥ worker_connections × worker_processes × 1.2,再通过 /proc/pid/limits 等验证实际生效。

调高 worker_rlimit_nofile 是 Nginx 应对高并发连接导致“too many open files”错误的关键一步,但它只是句柄资源管理的一环,必须配合系统级限制与 worker 进程配置协同生效。
理解 worker_rlimit_nofile 的作用范围
该指令设置的是每个 Nginx worker 进程能打开的最大文件描述符数量(即句柄数),仅影响 Nginx 自身进程,不改变系统全局或用户级限制。它必须小于等于 ulimit -n 的 soft limit,否则启动时会报错或静默截断。
- 若设为
65535,但系统未调整对应用户的 ulimit,则 Nginx 实际生效值仍为默认的 1024 - 该值不继承自 root 启动环境 —— 即使用 root 启动,worker 进程通常以非特权用户(如 www-data、nginx)身份运行,需针对该用户配置 ulimit
- 修改后必须重载(
nginx -s reload)或重启才能生效,且仅对新 fork 的 worker 生效
同步调整系统级文件句柄限制
仅改 Nginx 配置无法突破内核限制,需分三层对齐:
-
系统全局上限:检查
/proc/sys/fs/file-max,必要时写入/etc/sysctl.conf:fs.file-max = 2097152,然后执行sysctl -p -
用户级 soft/hard limit:在
/etc/security/limits.conf中添加(以运行 Nginx 的用户为例):nginx soft nofile 1048576nginx hard nofile 1048576
注意:SSH 登录需重新登录才加载,systemd 管理的服务需额外配置 -
systemd 服务覆盖:若用 systemd 启动 Nginx(常见于 CentOS 7+/Ubuntu 16.04+),需创建
/etc/systemd/system/nginx.service.d/override.conf:[Service]LimitNOFILE=1048576
再执行systemctl daemon-reload && systemctl restart nginx
合理设置 worker_rlimit_nofile 与 worker_connections 的关系
二者必须匹配,否则会造成资源浪费或瓶颈:
-
worker_rlimit_nofile应 ≥worker_connections × worker_processes,留出余量(建议 ≥ 1.2 倍)用于日志、上游连接、临时文件等 - 例如:4 个 worker 进程 + 每个支持 10240 连接 → 至少需要
worker_rlimit_nofile 50000 -
events { worker_connections 10240; }是单个 worker 能处理的并发连接数,受worker_rlimit_nofile和系统限制双重约束 - 避免盲目设极高值(如 200 万)——可能触发内核内存压力或调度开销上升,建议按实际峰值连接数 × 1.5 动态评估
验证是否真正生效
不能只看配置文件,要确认运行时值:
- 查 worker 进程当前限制:
cat /proc/$(pgrep -f "nginx: worker")/limits | grep "Max open files" - 观察错误日志是否仍有
accept() failed (24: Too many open files) - 用
lsof -p $(pgrep -f "nginx: worker") | wc -l统计实际打开句柄数,对比配置值是否接近 - 压测时监控
ss -s输出中的total和tcp连接数,确认未卡在系统层

















