文件描述符限制未生效是因systemd覆盖进程级设置,必须内核、用户、systemd单元、Nginx四层对齐;漏一层则worker_rlimit_nofile失效,需逐层验证LimitNOFILE、/proc//limits、fs.file-max及nginx.conf配置。

文件描述符限制没生效,不是改了配置就完事——Systemd 会覆盖进程级设置,必须四层对齐:内核、用户、systemd 单元、Nginx 自身。漏一层,worker_rlimit_nofile 就是摆设。
确认 systemd 是否接管了文件描述符限制
Systemd 不读 ulimit 或 /etc/security/limits.conf,它用自己的一套:
运行 systemctl show nginx | grep LimitNOFILE,看输出是否为期望值(如 LimitNOFILE=65536)。若显示 65536 但实际仍报 Too many open files,说明该限制未真正应用到 Nginx 进程。
检查方法:
• 找一个正在运行的 Nginx worker 进程 PID(ps aux | grep 'nginx: worker')
• 查它的实际限制:cat /proc/<pid>/limits | grep "Max open files"</pid>
• 若显示软限制仍是 1024,则 systemd 限制未生效,需继续排查
检查 systemd 单元文件中 LimitNOFILE 的写法与加载状态
直接编辑 /usr/lib/systemd/system/nginx.service 或 /etc/systemd/system/nginx.service 是危险操作。正确做法是创建覆盖片段:
管理和控制 macOS 系统功能。包括查看系统信息、管理进程、控制音量/亮度、 网络管理、电源管理、截图、剪贴板、Finder 操作等。当用户要求查看系统状态、 控制系统设置、管理进程、截图、调节音量亮度、查看网络信息、 关机重启睡眠等 Mac 系统操作时使用。
- 执行
sudo systemctl edit nginx,输入:
LimitNOFILE=65536
Restart=on-failure
- 保存后运行
sudo systemctl daemon-reload,再sudo systemctl restart nginx - 注意:不能只写数字,必须带单位(如
65536),也不能写成65536:65536—— systemd 不识别冒号分隔格式 - 若之前手动改过
/etc/security/limits.conf,它对 systemd 启动的服务完全无效,可删掉相关行避免干扰
验证 Nginx 配置中的 worker_rlimit_nofile 是否匹配
即使 systemd 设置了 65536,Nginx 主进程仍可能主动压低限制。打开 /etc/nginx/nginx.conf,确认存在且未被注释的指令:
- 该值不能超过 systemd 的
LimitNOFILE,否则启动时会被静默截断 - 修改后必须执行
nginx -t通过,再systemctl reload nginx(不是restart,避免中断连接) - 若使用
nginx -s reload而非systemctl reload nginx,systemd 会“失联”,导致后续LimitNOFILE变更不生效
排除内核级 file-max 不足的干扰
所有上层限制都依赖内核总池子。运行:
-
cat /proc/sys/fs/file-nr→ 看第一列(已分配 fd 数)是否接近第三列(file-max) -
cat /proc/sys/fs/file-max→ 默认值往往太小(如 8192),高并发场景建议设为1048576 - 临时调高:
sudo sysctl -w fs.file-max=1048576
永久生效:在/etc/sysctl.conf中添加fs.file-max = 1048576,再sudo sysctl -p
如果 dmesg | grep -i "file.*max" 有输出,说明内核已开始杀进程,这时光调 Nginx 没用。

















