首页/系统/信创系统运维速查/服务资源限制:MemoryMax 与 CPUQuota
服务与运维65 条

服务资源限制:MemoryMax 与 CPUQuota

用 cgroup 给服务设资源上限防单点拖垮整机:单元 drop-in 配 MemoryMax/CPUQuota,systemd-cgtop 看各单元实时占用;超限时 OOM 处理范围收敛在该单元内。

信创系统运维速查系统更新于 2026-10-13

给服务设资源上限

systemd 统一用 cgroup 管理服务资源:在单元里写 MemoryMax、CPUQuota 等字段,就能把某个服务的资源占用关在上限之内。最大的价值不是省资源,而是缩小故障范围——某个服务内存失控时,OOM 只在该单元内部发生,不会把整机的关键进程一起带走。systemd-cgtop 提供按单元的实时占用视图,用来确认限制是否真的生效。

基本信息

内存上限MemoryMax=(硬上限)、MemoryHigh=(软上限)
CPU 上限CPUQuota=百分比,150% 表示最多 1.5 个核
进程数TasksMax=
I/O 权重IOWeight=(相对权重)
查看占用systemd-cgtop -m、systemctl status 的资源段
生效方式daemon-reload 后重启对应服务

典型使用场景

  • 同一台机器上跑多个业务,防止单个服务吃满内存拖垮整机
  • 限制构建或批处理服务的 CPU,避免抢占在线请求的资源
  • 容器化之前的过渡方案:先用 systemd 单元做资源隔离
  • 排查内存异常时通过 cgtop 定位到具体是哪个单元在涨
  • 按业务等级给不同服务分配不同的资源配额

配置与生效

配置与生效
mkdir -p /etc/systemd/system/myapp.service.d      # drop-in 目录,避免直接改原单元文件
cat > /etc/systemd/system/myapp.service.d/20-limits.conf <<'EOF'
[Service]
MemoryMax=2G            # 硬上限,触顶在该单元内触发 OOM
CPUQuota=150%           # 最多使用 1.5 个核的算力
TasksMax=512            # 限制可创建的进程与线程总数
EOF
systemctl daemon-reload && systemctl restart myapp
systemctl show myapp -p MemoryMax -p CPUQuota -p TasksMax   # 确认取值已生效

观察与排障

观察与排障
systemd-cgtop -m                       # 按内存占用排序,实时看各单元使用了多少
systemctl status myapp | grep -iE 'memory|cpu'   # 状态输出里能看到当前占用与峰值
cat /sys/fs/cgroup/system.slice/myapp.service/memory.max 2>/dev/null   # cgroup v2 直接读限制值
journalctl -u myapp | grep -i -E 'oom|killed' | tail     # 被 OOM 杀掉的记录
systemd-cgls                            # 查看 cgroup 层级,确认服务归属哪个 slice

参数与效果

参数作用设错的表现
MemoryMax内存硬上限过小则服务被反复 OOM 重启
MemoryHigh内存软上限,超限先回收只设 High 不会阻止失控增长
CPUQuotaCPU 配额过小则请求排队、响应变慢
TasksMax进程与线程总数过小导致 fork 失败、连接建不上
IOWeightI/O 相对权重只影响竞争时的分配比例,不是硬上限
Slice归属的资源分组归错 slice 会继承另一套限制
CPUQuota=150% 表示至多得到一个半核的算力,它与 nice 不同:nice 只在竞争时影响调度顺序,CPUQuota 是硬性配额,超出部分会被限流。
cgroup 版本不同行为略有差异:cgroup v2 是当前主流,读限制值可看 /sys/fs/cgroup 下对应单元的 memory.max 等文件,v1 路径与字段名不同,排查前先确认版本。

易错点

  • MemoryMax 拍脑袋设得过小,服务被反复 OOM 杀掉并重启,业务表现为周期性中断,应先看历史峰值再留余量
  • 只设 MemoryHigh 不设 MemoryMax,超限只是加速回收,失控增长仍会拖垮整机
  • 改完 drop-in 文件忘记 daemon-reload 与重启服务,限制根本没生效却以为已经隔离
  • 把 IOWeight 当硬上限使用,它在无竞争时不会限制用量,磁盘仍可能被打满
  • 给服务设了 TasksMax 却忽略自身线程模型,连接数一上来就 fork 失败,报错指向业务代码而非资源限制

数据来源与参考

  • man 5 systemd.resource-control
  • man 1 systemd-cgtop
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌