必须依次配置内核参数fs.nr_open和fs.file-max、/etc/security/limits.conf及systemd的defaultlimitnofile,否则进程文件描述符限制仍为默认1024;ulimit仅临时生效且不继承,systemd服务需单独配置才生效。

直接改 /etc/sysctl.conf 并执行 sysctl -p 就能生效,但只管系统级总上限;真正影响进程的是用户级限制,必须配合 /etc/security/limits.conf 和 systemd 配置,否则多数服务(尤其是 systemd 启动的)依然卡在 1024。
为什么 ulimit -n 临时设置后重启就失效
因为 ulimit 只作用于当前 shell 及其子进程,不持久、不继承、不传递给 systemd 管理的服务。常见错误是只运行了 ulimit -SHn 65535,结果 Java 应用或 Nginx 一启动还是报 Too many open files。
-
ulimit -Sn查看软限制(实际生效值),ulimit -Hn查看硬限制(软限制不能超过它) - 软限制可由普通用户自行调高(只要不超过硬限制),硬限制只能 root 修改
- 即使设置了
ulimit,新登录会话、systemd 服务、SSH 子 shell 都不会自动继承
/etc/security/limits.conf 不生效的三个原因
这是最常踩的坑:配置写了,也 reboot 了,但 ulimit -n 还是 1024。根本原因是 CentOS 7 的 PAM 机制和 systemd 的双重限制叠加。
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离
- 必须用通配符
*或具体用户名写,不能只写root—— 多数服务以非 root 用户运行(如nginx、mysql) - 格式必须严格:
* soft nofile 65535和* hard nofile 65535两行都得有,且soft≤hard - systemd 会忽略
limits.conf,除非你额外修改/etc/systemd/system.conf中的DefaultLimitNOFILE
systemd 服务为什么始终拿不到新限制
CentOS 7 默认用 systemd 启动服务,而 systemd 在 fork 进程时不读取 limits.conf,它有自己的资源限制体系。
- 编辑
/etc/systemd/system.conf,取消注释并修改这两行:DefaultLimitNOFILE=65535DefaultLimitNPROC=65535 - 执行
systemctl daemon-reload,不是 reload 服务,而是重载 systemd 自身配置 - 如果服务用了自定义 unit 文件(比如
/etc/systemd/system/myapp.service),需在[Service]段显式加:LimitNOFILE=65535 - 验证方式:
cat /proc/$(pidof myapp)/limits | grep "Max open files",看Soft Limit是否已更新
要不要调 fs.file-max 和 fs.nr_open
大多数场景下不用动这两个内核参数,除非你明确遇到 kernel: VFS: file-max limit 65536 reached 这类内核日志。
-
fs.file-max是整个系统的文件描述符总数上限,设为fs.nr_open × 进程数的量级即可(例如 8G 内存建议 ≤ 524288) -
fs.nr_open是单个进程能申请的最大 fd 数,必须 ≥ 你设的hard nofile值,否则即使 limits.conf 设了 65535,进程也申请不到 - 修改后必须
sysctl -p生效,且要确保fs.nr_open ≥ fs.file-max,否则内核会静默截断
真正起效的关键顺序是:先调 fs.nr_open 和 fs.file-max → 再设 limits.conf → 最后改 systemd 的 DefaultLimitNOFILE。漏掉任意一环,都可能让某个环节卡在默认值上。尤其注意,systemd 的限制优先级高于 PAM,别以为改完 limits.conf 就万事大吉。










