ulimit限制需分临时、会话级、系统级三层,软硬限制不可倒挂,/etc/security/limits.conf需PAM支持,systemd服务须在unit文件中配置LimitNOFILE,fs.file-max与ulimit-n作用范围不同。

ulimit 限制不是“设了就生效”,必须分清临时设置、会话级生效、系统级持久化三个层次,否则服务一重启就退回默认值。
ulimit -n 设置不生效?检查软硬限制是否倒挂
常见现象:执行 ulimit -n 65535 后再查仍是 1024,或提示 bash: ulimit: open files: cannot modify limit: Operation not permitted。
根本原因是软限制(-S)试图超过当前硬限制(-H),而普通用户无权提升硬限制。
- 先查真实上限:
ulimit -Sn和ulimit -Hn必须都看 - 若
ulimit -Hn是 1024,那ulimit -Sn最高只能设到 1024 —— 此时改软限制毫无意义 - root 用户可临时提硬限:
ulimit -Hn 65535,之后普通用户才能设软限到 65535 - 非 root 用户执行
ulimit -n实际等价于ulimit -Sn,不会动硬限
/etc/security/limits.conf 配置后不生效?注意 PAM 加载顺序和登录方式
写进 /etc/security/limits.conf 是最常用的持久化方式,但大量人配完发现 ssh 登录后 ulimit -n 还是旧值。
关键点在于:PAM 的 limits.so 模块只对「通过 PAM 认证的登录会话」生效,且依赖配置加载顺序。
- 确认
/etc/pam.d/sshd或/etc/pam.d/login中存在这行:@include common-session或session required pam_limits.so - 图形界面(如 GNOME)通常绕过 PAM limits,需额外在
/etc/systemd/logind.conf中设DefaultLimitNOFILE=65535并重启systemd-logind - 用
su - username切换用户时,-表示模拟登录 shell,会触发 PAM;不带-则不会 - 配置格式必须严格:
username soft nofile 65535和username hard nofile 65535两行都要,不能合并
systemd 服务进程无视 limits.conf?得改 service 单元文件
用 systemctl start nginx 启动的服务,其子进程的 ulimit 完全不受 limits.conf 影响 —— 因为 systemd 不通过 PAM 启动服务进程。
必须显式在 service 文件中声明资源限制:
- 编辑
/etc/systemd/system/nginx.service.d/override.conf(若不存在则新建) - 加入:
[Service] LimitNOFILE=65535 LimitNPROC=4096
- 重载并重启:
systemctl daemon-reload && systemctl restart nginx - 验证:
systemctl show nginx | grep LimitNOFILE或查进程实际值:cat /proc/$(pidof nginx)/limits | grep "Max open files"
fs.file-max 和 ulimit -n 是两回事,别混用
有人看到 /proc/sys/fs/file-max 是 80 万,就以为单个进程也能开 80 万文件 —— 这是典型误解。
fs.file-max 是整个系统的文件描述符总数上限,由内核维护;ulimit -n 是单个进程能打开的上限,由 shell 和内核共同约束。
- 修改
fs.file-max用:sysctl -w fs.file-max=1000000,永久写入/etc/sysctl.conf - 但即使
fs.file-max很大,若ulimit -n是 1024,进程仍只能开 1024 个文件 - 反过来说,若
ulimit -n设太高(如 100 万),但fs.file-max只有 20 万,进程在达到 20 万时就会因系统级耗尽而失败 - 生产环境建议:设
fs.file-max≥ 所有关键服务ulimit -n× 预估并发进程数 × 1.2

















