“too many open files”需四层对齐:内核fs.file-max、用户limits.conf、systemd limitnofile、nginx worker_rlimit_nofile与worker_connections协同,缺一不可。

文件描述符(file descriptor)是 Nginx 高并发能力的底层基石。调不稳它,worker_processes 再多、worker_connections 再高,也会在连接激增时直接报 “Too many open files”,服务瞬间失能。真正有效的调优不是堆数字,而是让 进程级限制、系统级限制、内核行为、Nginx 配置四者严格对齐。
一、必须验证的三项系统级基线
这些不是“可选建议”,而是压测前必须为真(true)的前提条件:
-
ulimit -n 输出 ≥ worker_processes × worker_connections:例如 8 核 + 65535 连接/进程 → 至少需 524280。临时生效用
ulimit -n 655360,但仅限当前会话 -
/etc/security/limits.conf 中持久化设置:添加两行(* 表示所有用户,含 nginx 启动用户):
* soft nofile 655360* hard nofile 655360
修改后需重启用户会话或 reboot 才能对 systemd 管理的 nginx 生效 -
确认 nginx 主进程运行用户拥有该限制:用
ps -eo pid,user,comm | grep nginx查主进程 UID,再用cat /proc/<pid>/limits | grep "Max open files"</pid>直接验证该进程实际生效值
二、Nginx 配置中三个关键参数的协同逻辑
它们不是孤立字段,而是一条依赖链:
- worker_rlimit_nofile:设为与 ulimit -n 相同或略低(如 65535),表示单个 worker 进程最多能打开多少文件描述符。它必须 ≤ 系统级 hard limit
-
worker_connections:单个 worker 能处理的最大并发连接数。它的安全上限 = worker_rlimit_nofile − 已占用描述符(日志文件、配置文件、监听 socket 等)。生产推荐值为 4096~65535,但必须确保
worker_rlimit_nofile ≥ worker_connections + 100 -
worker_processes auto:自动匹配 CPU 核心数。此时总理论连接上限 =
cpu_cores × worker_connections。若混部其他服务,可手动设为 2 或 4,同时按比例下调 worker_connections,避免争抢
三、常见失效场景与快速定位方法
当出现连接拒绝、502/503 或错误日志里反复出现 “24: Too many open files” 时,按顺序排查:
- 查 nginx 错误日志头几行,确认报错时间点是否与流量高峰吻合
- 执行
lsof -u nginx | wc -l,看当前 nginx 用户打开的 fd 总数是否逼近 ulimit 限制 - 检查
cat /proc/sys/fs/file-nr:三个数字分别代表已分配、已使用、系统最大;第三项若远低于预期(如默认 8192),需在/etc/sysctl.conf中调大fs.file-max - 确认 nginx 是以 systemd 方式启动:如果是,
/etc/security/limits.conf对其无效,必须改用systemctl edit nginx添加LimitNOFILE=655360
四、生产环境推荐基线配置(8 核通用型)
以下为兼顾稳定性、可观测性与扩展性的最小可行配置片段:
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
<p>events {
use epoll;
worker_connections 65535;
multi_accept on;
accept_mutex off;
}</p><p>http {</p><h1>… 其他配置</h1><pre class="brush:php;toolbar:false;">log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" rt=$request_time uct=$upstream_connect_time '
'urt=$upstream_response_time';}
配套系统动作:设置 fs.file-max = 2097152,limits.conf 中 hard/soft nofile 均为 655360,并通过 nginx -t && systemctl reload nginx 生效。不复杂但容易忽略。











