4.4.5 控制组与systemd资源管理

控制组与systemd资源管理#

cgroups(控制组)用于按资源维度分组与限制进程;systemd 作为服务管理器,默认将每个服务挂载到 cgroup 层级,实现资源治理与审计。本节围绕 cgroup v2 与 systemd 结合的配置、验证、排错与练习展开。

1. 原理草图:systemd 与 cgroup 层级关系#

文章图片

2. 环境检查与基础命令#

  • 检查是否启用 cgroup v2
mount | grep cgroup
cat /sys/fs/cgroup/cgroup.controllers

预期:存在 cgroup2 挂载与控制器列表。

  • 查看层级与资源统计
systemd-cgls
systemd-cgtop

预期:看到 system.slice/nginx.service 等节点及 CPU/内存占用。

3. 关键资源指标与命令解释#

  • CPUCPUQuota(硬限制百分比)、CPUWeight(相对权重)
  • 内存MemoryHigh(软限制)、MemoryMax(硬限制)
  • IOIOReadBandwidthMax / IOWriteBandwidthMax
  • 进程数TasksMax
  • OOMOOMPolicy / OOMScoreAdjust

查看当前服务的限制:

systemctl show nginx.service \
  -p CPUQuota -p CPUWeight -p MemoryHigh -p MemoryMax -p TasksMax

4. 资源限制配置:临时与永久#

临时生效(动态调参):

# 将 nginx 限制为 50% CPU 与 1G 内存
systemctl set-property nginx.service CPUQuota=50% MemoryMax=1G

# 验证
systemctl show nginx.service -p CPUQuota -p MemoryMax

预期:显示 CPUQuota=50%MemoryMax=1073741824

永久生效(drop-in):

sudo mkdir -p /etc/systemd/system/nginx.service.d
sudo tee /etc/systemd/system/nginx.service.d/limit.conf >/dev/null <<'EOF'
[Service]
CPUQuota=40%
MemoryHigh=800M
MemoryMax=1G
TasksMax=1024
EOF

sudo systemctl daemon-reload
sudo systemctl restart nginx.service

5. 临时任务:systemd-run + cgroup 观察#

# 运行压测任务并限制资源
systemd-run --scope -p CPUQuota=30% -p MemoryMax=500M \
  stress --cpu 2 --vm 1 --vm-bytes 300M --timeout 60

# 观察限制效果
systemd-cgtop

命令解释:
- --scope:将前台进程纳入 systemd 管理
- -p:设置资源属性
- stress:模拟 CPU/内存消耗

6. cgroup v2 关键文件与验证#

# 进入服务 cgroup 路径
cd /sys/fs/cgroup/system.slice/nginx.service

# 查看限制与当前使用
cat cpu.max
cat memory.max
cat memory.current

预期:
- cpu.max 类似 200000 100000(2核限制)
- memory.max 对应设置的字节值

7. 常见问题与排错步骤#

问题1:限制未生效

systemctl status nginx.service
systemctl show nginx.service -p ControlGroup

排查要点:
- 确认服务由 systemd 启动
- 检查 drop-in 路径与 daemon-reload

问题2:内存 OOM 频繁

journalctl -u systemd-oomd --since "1 hour ago"
systemctl show nginx.service -p MemoryHigh -p MemoryMax -p OOMPolicy

建议:先提高 MemoryHigh,观察 oomd 行为。

问题3:CPU 限制无感

ps -eo pid,comm,ni,cls,rtprio | grep nginx

排查要点:
- 多进程服务会分摊 CPUQuota
- CPUQuota 是硬限制,CPUWeight 是相对权重

8. 综合示例:为批处理任务限速与隔离#

# 创建一个批处理服务单元
sudo tee /etc/systemd/system/batch-job.service >/dev/null <<'EOF'
[Unit]
Description=Batch Job with Resource Limits

[Service]
Type=simple
ExecStart=/usr/bin/bash -c 'for i in {1..5}; do dd if=/dev/zero of=/tmp/batch.$$ bs=1M count=200; sleep 2; done'
CPUQuota=20%
MemoryMax=300M
IOWriteBandwidthMax=/dev/sda 10M
TasksMax=200

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl start batch-job.service
systemctl status batch-job.service

预期:批处理任务占用受控,不挤占核心服务资源。

9. 练习题#

  1. mysql.service 限制为 MemoryMax=2G,并验证 cgroup 文件 memory.max 的值。
  2. 使用 systemd-run 运行 stress --cpu 4,设置 CPUQuota=25%,观察 systemd-cgtop 中的 CPU 变化。
  3. nginx.service 设置 IOReadBandwidthMaxIOWriteBandwidthMax,并用 dd 进行读写验证。

10. 最佳实践#

  • 核心服务优先使用 CPUWeight + 高 MemoryHigh;非核心服务使用 CPUQuota + MemoryMax
  • 结合 systemd-cgtop 与 Prometheus 监控持续优化配额。
  • nice/renice 配合,实现软硬优先级双层控制。