“Too many open files”是系统文件描述符四层限制(内核fs.file-max、用户limits.conf、systemd LimitNOFILE、nginx worker_rlimit_nofile与worker_connections)未对齐所致,须全部同步调优并逐层验证生效,缺一不可。

“Too many open files”不是 Nginx 配置写错了,而是系统对文件描述符(FD)的四层限制没对齐——内核、用户、进程启动环境、Nginx 自身配置,缺一不可。只改其中一层,比如只调 nginx.conf 或只跑 ulimit -n 65535,基本无效。
查清当前各层限制值
别靠猜,逐层验证实际生效值:
- 系统全局上限:
cat /proc/sys/fs/file-max(建议 ≥ 200000,高并发建议设为 1048576) - nginx 用户软/硬限制:
sudo -u nginx bash -c "ulimit -Sn && ulimit -Hn" - Nginx master 进程实际限制:
cat /proc/$(cat /var/run/nginx.pid)/limits | grep "Max open files" - Nginx worker 进程限制:
ps --ppid $(cat /var/run/nginx.pid) -o %p | sed '1d' | xargs -I{} cat /proc/{}/limits | grep "Max open files"
同步调优四层限制
必须全部配齐,顺序不重要,但漏一层就卡在 1024:
-
内核级:执行
sudo sysctl -w fs.file-max=1048576,再写入/etc/sysctl.conf持久化:echo "fs.file-max = 1048576" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p -
用户级(PAM 限制):编辑
/etc/security/limits.conf,添加两行(若 Nginx 以nginx用户运行):nginx soft nofile 65535nginx hard nofile 65535
确认/etc/pam.d/common-session(Ubuntu/Debian)或/etc/pam.d/login(CentOS/RHEL)中含session required pam_limits.so -
systemd 启动环境:若用 systemd 管理 Nginx,执行
sudo systemctl edit nginx,在[Service]下添加:LimitNOFILE=65535
然后重载并重启:sudo systemctl daemon-reload && sudo systemctl restart nginx -
Nginx 自身配置:在
/etc/nginx/nginx.conf的全局块(main context)添加:worker_rlimit_nofile 65535;
并在events块中确保worker_connections≤worker_rlimit_nofile(例如设为 4096 或 8192)
验证是否真正生效
重启 Nginx 后,再次检查 worker 进程的 /proc/*/limits,应显示类似:
Max open files 65535 65535 files
同时确认 error.log 不再出现 accept() failed (24: Too many open files) 或 socket() failed (24: Too many open files)。


















