ulimit -n 显示65536但nginx进程仍为1024,是因为systemd服务不读取limits.conf,而是继承自身unit文件中的LimitNOFILE配置;需在nginx.service中显式设置LimitNOFILE=65536并执行daemon-reload和restart。

为什么 ulimit -n 显示 65536,但 nginx 进程的 Max open files 还是 1024
因为 systemd 启动的服务压根不读 /etc/security/limits.conf——它绕过了 PAM 登录流程,自己用 cgroup 管理资源限制。你看到的 ulimit -n 是当前 shell 的软限制,对 systemctl start nginx 启动的进程完全无效。
怎么确认当前服务实际受哪个限制控制
别信 ulimit -n,直接查进程真实值:
-
cat /proc/$(pgrep nginx)/limits | grep "Max open files"—— 输出里 Soft 和 Hard 才是真实生效值 -
systemctl show nginx | grep LimitNOFILE—— 如果是空或显示LimitNOFILE=1024,说明 unit 文件没设或没重载 -
ps -o pid,uid,comm -p $(pgrep nginx)—— 确认进程 UID 是否匹配预期用户(比如不是意外以 root 跑的)
systemd 服务的 LimitNOFILE 必须显式配置且重载
改了 /etc/security/limits.conf 对 systemd 服务毫无作用。必须走 systemd 的路径:
- 单服务修改(推荐):
sudo systemctl edit nginx.service,写入:[Service] LimitNOFILE=65536
- 全局修改(谨慎):
sudo nano /etc/systemd/system.conf,取消注释并设DefaultLimitNOFILE=65536 - 改完必须执行:
sudo systemctl daemon-reload,再sudo systemctl restart nginx - 注意:仅
reload不生效,必须restart;systemctl kill --signal=SIGUSR2 nginx这类平滑重启也不更新 limits
Manjaro/Arch 用户特别容易漏掉 user.conf
桌面环境下,很多后台服务(如 dbus、pipewire、自启脚本)由 systemd --user 管理,它们只读 /etc/systemd/user.conf,和系统级 system.conf 分开:
-
sudo nano /etc/systemd/user.conf,设DefaultLimitNOFILE=65536 - 执行:
systemctl --user daemon-reload - 必须彻底退出图形会话再重新登录(不是新开终端),否则旧 session 还挂着老限制
- 验证:
systemctl --user show | grep LimitNOFILE
最容易被忽略的是:systemd 的限制是“启动时快照”,进程一旦运行,prlimit --nofile 只能临时调高 soft limit,但 hard limit 锁死,且重启后丢失。真正可靠的只有 unit 文件里的 LimitNOFILE 配置。


















