必须同步调高 ulimit -u 和 /proc/sys/kernel/pid_max,缺一不可;只改其一会导致高并发时因 PID 耗尽报“Resource temporarily unavailable”,因线程也占 PID,且 systemd 服务不继承 limits.conf 需单独配置 LimitNPROC。

改 ulimit -u 和 /proc/sys/kernel/pid_max 两个地方,缺一不可;只调一个,高并发时仍会报 Resource temporarily unavailable。
查清楚当前哪一层卡住了
别急着改配置,先确认是用户级限制、系统级上限,还是 systemd 服务没配对:
-
ulimit -u显示的是当前 shell 的软限制,只影响你手动启动的进程 - 进目标服务进程查真实值:
prlimit -n $PID | grep "MAX processes"(注意:prlimit -n实际查的是 nproc,不是 nofile) - 看系统总 PID 上限:
cat /proc/sys/kernel/pid_max,所有进程+线程加起来不能超这个数 - 统计当前已用线程数:
ps -eLf | wc -l,Linux 中线程也占 PID,很容易打满ulimit -u
/etc/security/limits.conf 配置后不生效的常见原因
写了 * soft nproc 65535 却没用,大概率栽在这几个点上:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- PAM 没加载
pam_limits.so:检查/etc/pam.d/common-session(Debian/Ubuntu)或/etc/pam.d/system-auth(RHEL/CentOS),必须有session required pam_limits.so - 只是
su - user,没真正重新登录:SSH 断开重连,或 console 重新 login,否则 PAM session 不触发 - 格式写错:
soft和hard必须分两行写,不能合并;*不管 root,建议显式加root soft nproc 65535 - 用了
sudo -u appuser command启动服务:这种调用不走 PAM 登录流程,limits.conf完全不生效
systemd 服务必须单独设 LimitNPROC=
nginx、redis、java 应用等由 systemctl 管理的服务,压根不读 /etc/security/limits.conf——这是最常被忽略的一环。
- 单服务配置:编辑
/etc/systemd/system/myservice.service,在[Service]段加LimitNPROC=65535 - 全局生效(慎用):在
/etc/systemd/system.conf中设DefaultLimitNPROC=65535,再执行systemctl daemon-reload - 验证是否生效:
systemctl show myservice | grep LimitNPROC,或查进程实际值:prlimit -n $(pidof myservice)
/proc/sys/kernel/pid_max 设太小会导致 fork 失败
当 ulimit -u 调到 65535,但 pid_max 还卡在默认 32768,就会出现“用户允许开 65535 个线程,但内核连 PID 都分不出”的情况。
- 临时修改:
sudo sysctl -w kernel.pid_max=4194304 - 永久生效:在
/etc/sysctl.conf加kernel.pid_max = 4194304,再执行sudo sysctl -p - x86_64 架构上限约 4194304,设太高可能增加调度开销;一般生产环境设为 131072 或 196608 更稳妥
真正难的不是改哪一行配置,而是得同时盯住四个地方:当前会话的 ulimit -u、PAM 加载的用户级 nproc、systemd 服务的 LimitNPROC、内核的 pid_max。漏掉任意一层,都可能在凌晨三点收到告警。

















