必须同步配置内核级fs.file-max、用户级limits.conf软硬限制及systemd服务limitnofile三层,缺一不可;ulimit -n仅临时生效,永久生效需分别配置三者并重启会话或服务。

直接改 /etc/security/limits.conf 不生效?那大概率是没配对层级,或者漏了系统级总上限。CentOS 7+ 的文件打开数限制分三层:内核全局上限(fs.file-max)、用户级软硬限制(nofile)、服务级独立限制(LimitNOFILE),缺一不可。
为什么 ulimit -n 改了但程序还是报 “too many open files”
常见错误是只调了用户限制,却忘了内核总池子太小。比如你设了 * hard nofile 65535,但 cat /proc/sys/fs/file-max 返回才 180965,表面看够用;可一旦并发进程多,每个进程都占几百 fd,很快耗尽全局池——此时哪怕单个进程的 ulimit 没超,也会因内核无法分配新 fd 而失败。
-
fs.file-max是整个系统能分配的文件描述符总数,建议按内存估算:每 256 个 fd 约占 4MB 内存,8GB 内存机器设到524288比较稳妥 - 修改后必须运行
sysctl -p生效,否则重启前无效 - 如果
sysctl -p报错 “cannot assign requested address”,说明值超了内核允许上限,需查/proc/sys/fs/nr_open(该值为硬上限,不能高于它)
/etc/security/limits.conf 配置不生效的典型原因
这个文件只对 PAM 登录会话生效,systemd 服务、crond 启动的进程、SSH 直接执行命令(非登录 shell)都不走这套逻辑。所以即使你写了 * soft nofile 65535,Java 应用跑在 systemd 里照样卡在 1024。
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离
- 必须确保
/etc/pam.d/sshd和/etc/pam.d/login包含这一行:session required pam_limits.so - 普通用户修改后要重新登录(不是新开 terminal),root 用户也一样
- 不要用
root或具体用户名替代*来设全局限制——*才覆盖所有登录用户,包括通过 sudo -i 切换的用户 - 软限制(
soft)不能超过硬限制(hard),且用户只能调低硬限制、不能调高
systemd 服务怎么单独提上限
Tomcat、Nginx、Kafka 这类服务几乎都用 systemd 管理,它们不读 limits.conf,必须显式配置。否则就算你把用户限制设到百万,服务启动时依然沿用 systemd 默认的 4096。
- 编辑服务 unit 文件,如
/etc/systemd/system/myapp.service - 在
[Service]段下加:LimitNOFILE=65535(注意不是limitnofile,大小写敏感) - 改完必须执行:
systemctl daemon-reload && systemctl restart myapp - 验证是否生效:
cat /proc/$(pidof myapp)/limits | grep "Max open files"
真正麻烦的不是改哪几个数字,而是三层限制之间有依赖关系:内核总池子 fs.file-max 必须大于所有用户 + 服务的 nofile 之和;而每个服务的 LimitNOFILE 又不能超过它所属用户的硬限制。漏掉任意一层,都会在高并发或大数据场景下突然崩出 “too many open files”。










