资源限制是什么
由 systemd 拉起的服务,资源限制写在单元文件的 [Service] 段,而不是 /etc/security/limits.conf——后者只对登录会话(PAM 体系)生效,对 systemd 服务不起作用。这里有两类机制:LimitNOFILE、LimitNPROC 这类是进程 rlimit,由内核在 fork 时设定;MemoryMax、CPUQuota、TasksMax 属于 cgroup 控制器,按控制组整体计量与强制。
基本信息
| 用途 | 限制或放开单个服务的文件描述符、进程数、内存与 CPU |
|---|---|
| 语法 | 在 [Service] 段写 Limit* / Memory* / CPU* / Tasks* 指令 |
| 所属 | systemd(systemd.exec 与 systemd.resource-control 定义) |
| 生效方式 | daemon-reload 后 restart 服务;cgroup 类限制对已在运行的进程需重启才生效 |
典型使用场景
- 高并发服务报 Too many open files:把 LimitNOFILE 调大,这是最常见的调整
- 防单服务吃满内存:给服务设 MemoryMax,避免拖垮整台机器
- 限制 CPU 争抢:给次要服务设 CPUQuota,保证关键业务有算力
- 限制进程数:防止 fork 泄漏把进程表耗尽,用 TasksMax 封顶
- 排查 OOM 原因:确认是 cgroup 内存上限触发还是整机内存不足
常用限制示例
常用限制示例
[Service]
LimitNOFILE=65535 # 单进程可打开的文件描述符上限
LimitNPROC=4096 # 该服务的进程/线程数上限
MemoryHigh=1800M # 软限制:超过后内核回收更积极
MemoryMax=2G # 硬限制:超过即触发 OOM 处理
CPUQuota=200% # 最多用满两个核
TasksMax=512 # 控制组内任务数上限验证生效情况
验证生效情况
systemctl show myapp -p LimitNOFILE -p MemoryMax -p TasksMax
cat /proc/$(systemctl show -p MainPID --value myapp)/limits | grep -i 'open files'
systemd-cgls --no-pager -u myapp | head # 看控制组里有哪些进程
cat /sys/fs/cgroup/system.slice/myapp.service/memory.events 2>/dev/null # 看 oom 计数常用指令对照
| 指令 | 约束对象 | 说明 |
|---|---|---|
| LimitNOFILE | 进程 rlimit | 文件描述符上限,高并发服务常需调大 |
| LimitNPROC | 进程 rlimit | 该用户的进程总数上限,注意是用户级口径 |
| LimitCORE | 进程 rlimit | 核心转储大小,排查崩溃时可能需临时放开 |
| MemoryHigh / MemoryMax | cgroup 内存 | 软限制引发回收,硬限制触发 OOM 处置 |
| CPUQuota | cgroup CPU | 按百分比配额,200% 表示两个核的算力 |
| TasksMax | cgroup pids | 控制组内任务数上限,防 fork 炸弹 |
LimitNOFILE 有继承关系:单元没写时用 Manager 的 DefaultLimitNOFILE。只调 systemd 这一层还不够,应用自身的连接池与文件上限配置也要同步调整,否则瓶颈只是换了个地方。
MemoryMax 设得过小时,服务会被周期性杀死,而 journal 里往往只有一条简短的 OOM 记录,很容易被误判成应用崩溃。调小上限后要留意 cgroup 的 oom 计数。