“too many open files”本质是nginx worker进程创建socket时被系统拒绝,因文件描述符(fd)耗尽;须同步调优内核fs.file-max、用户limits.conf、systemd limitnofile及nginx.conf中worker_rlimit_nofile与worker_connections,缺一不可。

这个报错本质是 Nginx worker 进程尝试创建新 socket 时,被系统拒绝——因为已用尽允许打开的文件描述符(file descriptor,简称 fd)。Linux 中 socket、文件、管道等都算作 fd,而每个进程有独立上限。解决的关键不是“修错误”,而是**逐层打通限制链路**:系统级 → 进程级 → Nginx 配置级。
查清当前真实限制值
别猜,先看实际数字:
- 运行 ulimit -n 查当前 shell 的 soft limit(影响新启动的 Nginx)
- 查 Nginx 主进程 PID:pgrep nginx,再执行 cat /proc/[PID]/limits | grep "Max open files",确认它真正生效的值
- 查系统总容量:cat /proc/sys/fs/file-max,若低于 100 万,高并发场景下可能成瓶颈
- 统计当前打开数:lsof -p [PID] | wc -l,对比上面的 Max 值,看是否已逼近上限
永久提升系统级进程限制
仅改 ulimit 命令只对当前终端有效,重启即失效。必须落盘配置:
- 编辑 /etc/security/limits.conf,末尾添加两行(* 表示所有用户,包括 nginx 启动用户):
* soft nofile 65535
* hard nofile 65535 - 若使用 systemd(现代主流),还需补充服务级限制:
新建 /etc/systemd/system/nginx.service.d/override.conf,写入:
[Service]
LimitNOFILE=65535 - 保存后,重载配置:systemctl daemon-reload,并完全重启 nginx(不是 reload)
同步调整 Nginx 自身配置
worker_rlimit_nofile 不是可选优化项,它是必要声明。它告诉每个 worker 进程:“你最多能用这么多 fd”,但前提是系统允许。
- 在 nginx.conf 的 main 块(全局块,不在 http 或 events 内) 添加:
worker_rlimit_nofile 65535; - 同时检查 events 块 中的 worker_connections,建议设为相同或略低值(如 65535),避免理论连接数超过 fd 上限
- 注意:若 worker_rlimit_nofile 设为 100000,但系统 hard limit 只有 65535,Nginx 启动时会静默降级或报错,务必前后一致
别漏掉内核总容量和资源泄漏
即使单进程调高了,系统总池子太小也不行;就算配置全对,程序不关 fd,迟早还会爆。
- 临时扩大系统总 fd 池:sysctl -w fs.file-max=2097152
- 永久生效:在 /etc/sysctl.conf 加一行 fs.file-max = 2097152,再运行 sysctl -p
- 用 lsof -p [nginx_pid] | awk '{print $9}' | sort | uniq -c | sort -nr | head -10 查看哪些路径或端口被高频打开,判断是否真有连接未释放、日志轮转异常或 upstream 长连接堆积










