centos 7+ 中句柄限制需分三层配置:/etc/security/limits.conf(仅对pam登录用户生效)、/etc/systemd/system.conf 中 defaultlimitnofile(全局systemd服务默认值)、单个service文件中 limitnofile(服务专属覆盖),三者缺一不可,且systemd服务完全不读取limits.conf。

CentOS 的句柄限制必须分三层改,只动 /etc/security/limits.conf 是无效的 —— 尤其对 systemd 服务(比如 nginx、mysql、java 应用)完全不起作用。
为什么 ulimit -n 改了却没用?
因为 ulimit 只影响当前 shell 启动的子进程,且软硬限制需同时设;更重要的是:systemd 管理的服务根本**不读取 limits.conf**,它走的是自己的资源控制路径。
-
ulimit -n 65535仅对当前终端 session 有效,新开终端或重启后丢失 -
ulimit -Sn 65535和ulimit -Hn 65535必须都执行,否则软限制可能仍卡在 1024 - 即使
limits.conf配好了,systemctl start myapp.service启动的进程依然沿用 systemd 默认的DefaultLimitNOFILE=1024
systemd 服务的句柄数怎么真正生效?
CentOS 7+ 使用 systemd,服务的资源限制由 systemd 全局配置或单个 service 文件控制,/etc/security/limits.conf 对它完全透明。
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离线兼容性测试。
- 修改全局默认值:
sudo vi /etc/systemd/system.conf,取消注释并设为:DefaultLimitNOFILE=655350 DefaultLimitNPROC=65535
- 改完必须执行:
sudo systemctl daemon-reload(注意:不需要 reboot,但已有服务需 restart 才生效) - 若只想改某个服务(如
nginx.service),直接编辑:sudo systemctl edit nginx.service,写入:[Service] LimitNOFILE=655350
- 验证是否加载成功:
systemctl show nginx.service | grep LimitNOFILE
/etc/security/limits.conf 还要不要配?
要,但只对**非 systemd 启动的交互式登录用户**(比如 ssh 登录后手动运行 java、python 脚本)起作用。漏配会导致运维排查时误判。
- 确保
/etc/pam.d/sshd或/etc/pam.d/login包含这一行:session required pam_limits.so - 在
/etc/security/limits.conf中添加(注意顺序和空格):* soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535
- 普通用户修改后需**重新 ssh 登录**(不是
su -),否则ulimit -n仍显示旧值 - 若用
sudo -i切换 root,实际继承的是原用户 limits,不是 root 的配置
系统级最大文件数(fs.file-max)怎么设才合理?
这是内核允许打开的**总文件描述符上限**,必须 ≥ 单进程最大值 × 预估并发进程数,否则再调高单进程也没用。
- 临时生效:
echo 6553560 | sudo tee /proc/sys/fs/file-max - 永久生效:在
/etc/sysctl.conf中加一行:fs.file-max = 6553560,然后运行sudo sysctl -p - 检查当前使用量:
cat /proc/sys/fs/file-nr输出三列,第三列是file-max,第一列是已分配的 fd 数 - 别盲目堆大数值 —— 每个 fd 占约 1KB 内核内存,设到 1000 万可能吃掉 10GB RAM
最容易被忽略的一点:改完所有配置后,systemd 服务必须 restart(不是 reload),且得确认该服务没在 [Service] 段里硬编码了 LimitNOFILE 覆盖全局设置。










