CentOS 7 文件描述符限制需同步配置 PAM、systemd 和内核参数:PAM 需在 /etc/pam.d/sshd 等文件中启用 pam_limits.so;systemd 服务须单独配置 LimitNOFILE;内核参数 fs.nr_open 必须 ≥ 单进程 ulimit 值且 ≤ fs.file-max。

CentOS 7 不是“节点数”,而是“文件描述符数”(file descriptor limit)——改错方向,后面全白调。
为什么 ulimit -n 显示 1024 却改不动?
这不是权限不够,而是 PAM 机制没生效。CentOS 7 默认启用 PAM 资源限制,但 /etc/pam.d/sshd 或 /etc/pam.d/login 中缺少 pam_limits.so 调用,导致 /etc/security/limits.conf 配置被忽略。
- 检查是否加载:运行
grep limits /etc/pam.d/sshd,若无输出,说明未启用 - 必须手动在
/etc/pam.d/sshd开头或末尾添加一行:session required pam_limits.so - 如果用
su切换用户,还要确认/etc/pam.d/su里也有该行 - 改完必须重新建立 SSH 连接(不是
systemctl restart sshd),否则旧会话仍沿用旧限制
/etc/security/limits.conf 里写 * 还是写具体用户名?
写 * 看似省事,但对 systemd 服务(如 mysqld、java 进程)基本无效——systemd 会绕过 PAM limits,走自己的资源控制逻辑。
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离
- 对交互式登录用户(SSH 登录的 shell):写
*或具体用户名都生效 - 对 systemd 启动的服务:必须单独配置
/etc/systemd/system/<service>.service.d/override.conf</service> - 例如为
nginx提升限制:[Service]<br>LimitNOFILE=1048576<br>LimitNPROC=1048576
- 改完要执行:
systemctl daemon-reload && systemctl restart nginx
fs.file-max 和 fs.nr_open 哪个先设?
顺序不能错:fs.nr_open 必须 ≥ 你打算设的单进程最大值(比如 ulimit -n 1048576),否则内核会静默截断为你设的 nr_open 值;而 fs.file-max 必须 ≥ fs.nr_open,否则 nr_open 设置会被拒绝。
- 查当前值:
cat /proc/sys/fs/nr_open(默认约 1048576)、cat /proc/sys/fs/file-max - 先设
fs.nr_open(如需超默认值):echo 'fs.nr_open = 2097152' >> /etc/sysctl.conf - 再设
fs.file-max:echo 'fs.file-max = 4194304' >> /etc/sysctl.conf - 最后执行:
sysctl -p
改完还是报 too many open files?重点查这三处
常见漏点不是配置没写,而是生效路径断在中间。
- 确认进程实际运行用户:用
ps -eo user,comm | grep your_process,确保 limits 是给这个用户配的 - 检查进程启动方式:如果是通过
systemd启动,limits.conf完全不生效,只认LimitNOFILE - 验证当前进程真实限制:
cat /proc/$(pidof your_process)/limits | grep "Max open files",别信ulimit -n当前 shell 的值 - 注意:容器环境(Docker/Podman)中,宿主机 limits 不自动继承,需在
docker run --ulimit nofile=...显式传入
真正卡住的往往不是数值设多大,而是哪一层(PAM / systemd / 容器 runtime)接管了限制,以及你查的是谁的限制、改的是谁的配置。

















