在华为鲲鹏服务器(openEuler 操作系统)上,我们经常需要调整系统的资源限制,比如增大 open files(最大打开文件数)或 max user processes(最大用户进程数),以满足数据库(如 MongoDB、MySQL)或中间件(如 Nginx、Tomcat)的高并发需求。
然而,很多开发者会发现:明明修改了 /etc/security/limits.conf,但 ulimit -a 显示的值却没有变化;或者修改了服务的 systemd 单元文件,重启后限制依然还是 1024。这类问题通常源于对 Linux 资源限制机制的不了解。
本文将结合 openEuler 系统的实际特点,从 PAM 认证机制、systemd 服务管理、常见踩坑点三个维度,完整复盘如何排查并解决 ulimit 配置不生效的问题。
2. 背景知识:Linux 资源限制的两套体系
在 Linux 中,资源限制(rlimit)最终通过 setrlimit() 系统调用实现,但谁来调用、何时调用,取决于进程的启动方式:
openEuler 系统(基于 CentOS/RHEL 体系)同时支持上述两套体系,但它们的配置互不干扰。如果你修改了 limits.conf 却发现某个 systemd 服务不生效,那是正常的——因为服务根本不走 PAM。
3. 典型问题场景及排查步骤
3.1 场景一:用户通过 SSH 登录后 ulimit -n 仍是 1024
现象:
bash
明明 /etc/security/limits.conf 中已经配置了:
text
排查步骤:
① 确认 PAM 是否调用了 pam_limits.so
检查 /etc/pam.d/sshd 文件(SSH 登录):
bash
如果没有任何输出,再看该文件是否通过 include 引用了其他公共文件,例如:
text
然后检查被引用的文件(如 /etc/pam.d/password-auth)是否包含:
text
openEuler 默认配置:password-auth 和 system-auth 中通常会包含 pam_limits.so,因此无需在 sshd 中单独添加。
② 确认 pam_limits.so 模块是否存在
bash
若不存在,重新安装 PAM 包:
bash
③ 检查 limits.conf 语法
每行必须符合 <domain> <type> <item> <value> 格式,常见错误:
- 遗漏
domain(如写成 soft nofile 65536 缺少开头的 *) item 拼写错误(如 nofile 写成了 openfile)- 值超过内核上限(
nofile 不能超过 /proc/sys/fs/nr_open,默认 1048576)
④ 添加日志调试
在 /etc/pam.d/password-auth 的 pam_limits.so 行后添加 debug:
text
重新登录并查看日志:
bash
看到类似 pam_limits(sshd:session): reading settings from /etc/security/limits.conf 即表示模块已执行。
⑤ 重新登录
关键点:PAM 配置只在会话建立时读取一次。修改后必须 退出当前 SSH 会话并重新登录,而不是执行 source ~/.bashrc。
3.2 场景二:修改了 limits.conf,但某个 systemd 服务(如 mongodb)仍受 1024 限制
原因:systemd 服务完全绕过 PAM,不会读取 limits.conf。
解决方法:通过 systemd 单元文件单独设置。
方法一:使用 systemctl edit 添加覆盖配置(推荐)
bash
写入:
ini
保存退出,重载并重启:
bash
方法二:修改全局 systemd 默认值(影响所有服务)
编辑 /etc/systemd/system.conf,取消注释并修改:
text
执行 systemctl daemon-reexec 生效。
验证服务实际限制:
bash
3.3 场景三:普通用户无法调高 ulimit -n 到期望值
现象:普通用户执行 ulimit -n 65536 报错 Operation not permitted。
原因:当前 Shell 的硬限制(hard limit) 低于期望值。只有 root 可以调高硬限制。
解决方法:
在 /etc/security/limits.conf 中为对应用户设置 hard nofile,然后重新登录。例如:
text
3.4 场景四:* 通配符不覆盖 root 用户
注意:在 limits.conf 中,* 代表“所有普通用户”,不包括 root。如果需要为 root 设置限制,必须明确写出:
text
4. openEuler 特有的注意事项
- PAM 配置文件路径:openEuler 沿用 RHEL 体系,PAM 文件位于
/etc/pam.d/,公共配置为 password-auth 和 system-auth。 - 默认硬限制:openEuler 22.03 及更高版本中,用户进程的默认硬限制可能由 systemd 用户实例管理,建议优先修改
limits.conf 搭配 PAM。 - 鲲鹏架构兼容性:
pam_limits.so 在 aarch64 下路径为 /lib64/security/pam_limits.so,与 x86_64 一致,无需特殊处理。
5. 快速排坑检查清单
6. 实战案例:在 openEuler 上为 MongoDB 调高文件描述符
需求:MongoDB 需要最大打开文件数 65536。
步骤:
- 修改系统 PAM 配置(已默认开启,跳过)。
- 编辑 MongoDB 服务覆盖文件:
- bash
- 添加:
- ini
- 重载 systemd:
- bash
- 验证:
- bash
- 输出应为
65536 65536 files。
7. 总结
ulimit 配置不生效的根本原因在于:没有对准正确的配置入口。
- 对于交互式用户会话 → 检查 PAM 和
/etc/security/limits.conf - 对于 systemd 服务 → 检查单元文件中的
LimitXXX= 指令 - 对于容器化环境(Docker/K8s) → 还需考虑容器运行时自身的限制
在华为鲲鹏 openEuler 系统上,上述规则同样适用。掌握这套排查方法论,就能快速定位并解决 90% 的资源限制问题。
附:常用调试命令速查
bash
在华为鲲鹏服务器(openEuler 操作系统)上,我们经常需要调整系统的资源限制,比如增大
open files(最大打开文件数)或max user processes(最大用户进程数),以满足数据库(如 MongoDB、MySQL)或中间件(如 Nginx、Tomcat)的高并发需求。然而,很多开发者会发现:明明修改了
/etc/security/limits.conf,但ulimit -a显示的值却没有变化;或者修改了服务的 systemd 单元文件,重启后限制依然还是 1024。这类问题通常源于对 Linux 资源限制机制的不了解。本文将结合 openEuler 系统的实际特点,从 PAM 认证机制、systemd 服务管理、常见踩坑点三个维度,完整复盘如何排查并解决
ulimit配置不生效的问题。2. 背景知识:Linux 资源限制的两套体系
在 Linux 中,资源限制(rlimit)最终通过
setrlimit()系统调用实现,但谁来调用、何时调用,取决于进程的启动方式:pam_limits.so→ 读取/etc/security/limits.conf及limits.d/*.conf/etc/security/limits.confLimitXXX=指令/etc/systemd/system.conf(全局)或服务覆盖文件openEuler 系统(基于 CentOS/RHEL 体系)同时支持上述两套体系,但它们的配置互不干扰。如果你修改了
limits.conf却发现某个 systemd 服务不生效,那是正常的——因为服务根本不走 PAM。3. 典型问题场景及排查步骤
3.1 场景一:用户通过 SSH 登录后
ulimit -n仍是 1024现象:
bash
明明
/etc/security/limits.conf中已经配置了:text
排查步骤:
① 确认 PAM 是否调用了
pam_limits.so检查
/etc/pam.d/sshd文件(SSH 登录):bash
如果没有任何输出,再看该文件是否通过
include引用了其他公共文件,例如:text
然后检查被引用的文件(如
/etc/pam.d/password-auth)是否包含:text
② 确认
pam_limits.so模块是否存在bash
若不存在,重新安装 PAM 包:
bash
③ 检查
limits.conf语法每行必须符合
<domain> <type> <item> <value>格式,常见错误:domain(如写成soft nofile 65536缺少开头的*)item拼写错误(如nofile写成了openfile)nofile不能超过/proc/sys/fs/nr_open,默认 1048576)④ 添加日志调试
在
/etc/pam.d/password-auth的pam_limits.so行后添加debug:text
重新登录并查看日志:
bash
看到类似
pam_limits(sshd:session): reading settings from /etc/security/limits.conf即表示模块已执行。⑤ 重新登录
关键点:PAM 配置只在会话建立时读取一次。修改后必须 退出当前 SSH 会话并重新登录,而不是执行
source ~/.bashrc。3.2 场景二:修改了
limits.conf,但某个 systemd 服务(如 mongodb)仍受 1024 限制原因:systemd 服务完全绕过 PAM,不会读取
limits.conf。解决方法:通过 systemd 单元文件单独设置。
方法一:使用
systemctl edit添加覆盖配置(推荐)bash
写入:
ini
保存退出,重载并重启:
bash
方法二:修改全局 systemd 默认值(影响所有服务)
编辑
/etc/systemd/system.conf,取消注释并修改:text
执行
systemctl daemon-reexec生效。验证服务实际限制:
bash
3.3 场景三:普通用户无法调高
ulimit -n到期望值现象:普通用户执行
ulimit -n 65536报错Operation not permitted。原因:当前 Shell 的硬限制(hard limit) 低于期望值。只有 root 可以调高硬限制。
解决方法:
在
/etc/security/limits.conf中为对应用户设置hard nofile,然后重新登录。例如:text
3.4 场景四:
*通配符不覆盖 root 用户注意:在
limits.conf中,*代表“所有普通用户”,不包括 root。如果需要为 root 设置限制,必须明确写出:text
4. openEuler 特有的注意事项
/etc/pam.d/,公共配置为password-auth和system-auth。limits.conf搭配 PAM。pam_limits.so在 aarch64 下路径为/lib64/security/pam_limits.so,与 x86_64 一致,无需特殊处理。5. 快速排坑检查清单
ulimit -agrep pam_limits /etc/pam.d/sshd /etc/pam.d/password-authsession required pam_limits.socat /etc/security/limits.confsystemctl cat <service> | grep LimitLimitNOFILE=sysctl fs.file-max、cat /proc/sys/fs/nr_opennofile不能超过nr_open6. 实战案例:在 openEuler 上为 MongoDB 调高文件描述符
需求:MongoDB 需要最大打开文件数 65536。
步骤:
65536 65536 files。7. 总结
ulimit配置不生效的根本原因在于:没有对准正确的配置入口。/etc/security/limits.confLimitXXX=指令在华为鲲鹏 openEuler 系统上,上述规则同样适用。掌握这套排查方法论,就能快速定位并解决 90% 的资源限制问题。
附:常用调试命令速查
bash