登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

systemd-cgtop 怎样观察服务资源占用

来源:17golang原创

时间:2026-10-15 05:44:53 380浏览 收藏

线上排查systemd托管服务资源突增的问题时,普通top工具只能拿到单个进程的资源数据,没法直接按服务维度统计聚合,用系统原生自带的systemd-cgtop就可以直接按控制组维度汇总所有托管服务的CPU、内存、IO占用情况,定位异常的效率高很多。

systemd-cgtop 是所有systemd主流发行版默认预装的轻量工具,不需要额外安装任何第三方依赖,就能直接展示所有systemd管理的服务、切片、用户控制组的实时资源占用,支持自定义排序规则和采样间隔。

服务出现 CPU 飙高、内存持续上涨或磁盘读写异常时,我通常先要回答一个很具体的问题:到底是哪个 systemd 管理的 cgroup 在占用资源?systemd-cgtop适合做这个“现场观察”。它按 cgroup 层级显示任务数、CPU、内存和磁盘 I/O,并按固定间隔刷新;它解决的是当前状态定位,不是历史趋势存储。

官方地址:https://www.freedesktop.org/software/systemd/man/latest/systemd-cgtop.html

先记住三个判断:用 --order=cpu、--order=memory 或 --order=io 把当前最突出的资源排到前面;内存和 I/O 没有数据时,优先检查对应 accounting/controller;CPU 百分比可以超过 100%,因为它按处理器总数累计。

先看清 systemd-cgtop 观察的是什么

systemd-cgtop观察的是 Linux control group 层级。一个服务 unit 下面可能还有线程、子进程或子 cgroup,所以表格中的一行不一定等于一个 PID。这个差异很重要:当一个服务拉起多个工作进程时,按 cgroup 看更接近 systemd 的资源归属,按进程看则更适合追单个异常进程。

默认情况下它类似于实时 top,每秒刷新一次。开始排查时不要急着修改资源限制,先把“哪个层级靠前”和“哪一列靠前”记录下来。CPU、内存和 I/O 是三个不同的线索,排序方式不同,得到的第一名也可能不同。

systemd-cgtop 中服务 cgroup、任务数、CPU、内存和磁盘 I/O 的静态关系说明图
图1:systemd-cgtop 资源表与 cgroup 层级的静态关系说明图,不是终端截图或运行证据。

用一次基础观察确定资源方向

直接执行下面的命令可以打开交互式观察界面。命令本身只读取实时统计,不会改变服务配置;退出时使用 q。

# 打开 cgroup 资源观察界面,默认按 CPU 负载排序
systemd-cgtop

# 只观察内存占用靠前的 cgroup
systemd-cgtop --order=memory

# 只观察磁盘 I/O 活跃的 cgroup
systemd-cgtop --order=io

进入界面后,可以用 p、t、c、m、i分别按路径、任务数、CPU、内存和 I/O 排序。排查时我会先按 CPU 看一遍,再按内存和 I/O 各看一遍,避免把“CPU 不高”误判成服务没有资源问题。

如果只关心某个 cgroup 子树,可以在命令末尾给出路径。路径来自 systemd 的 cgroup 层级,常见服务会位于类似/system.slice/example.service的位置;实际路径应以主机当前的 unit 层级为准。

# 把观察范围收窄到一个服务所在的 cgroup 子树
systemd-cgtop /system.slice/example.service

# 只显示较浅的层级,减少大量子 cgroup 干扰
systemd-cgtop --depth=2 --order=cpu

让实时输出更贴近当前排障问题

默认三层深度适合快速浏览,但服务树较大时,过多层级会让真正的问题行被淹没。--depth=0只看根组,--depth=1看第一层;逐步增加深度,比一开始把整棵树展开更容易建立判断。

# 每 2 秒刷新一次,适合观察较慢的资源变化
systemd-cgtop --delay=2s --order=memory

# 只显示服务树的前两层,并按 CPU 排序
systemd-cgtop --depth=2 --order=cpu

# 切换 CPU 显示口径:percentage 是百分比,time 是累计 CPU 时间
systemd-cgtop --cpu=percentage
systemd-cgtop --cpu=time

任务数默认可能按线程粒度统计。若排查的是“到底有多少用户态进程”,可以使用-P,它会排除内核线程,并把一个用户态进程按一个进程计数;如果关心用户态进程加内核线程,但不想把同一进程的每条用户线程分别算入,可以考虑-k。这两个选项不能同时使用。

# 用用户态进程数量替代默认的逐任务观察口径
systemd-cgtop -P --order=tasks

# 在脚本中降低刷新频率,避免观察命令本身制造过多终端输出
systemd-cgtop -P --delay=3s --order=tasks

这一步的目标只是把输出变得可读,不是给服务设置 CPU、内存或 I/O 限额。观察命令和资源控制属于两个动作,混在一起会让故障现场更难复原。

空白数据不一定代表服务没有占用

systemd 文档特别强调,内存统计需要memory控制器,磁盘 I/O 统计需要io控制器;对应 unit 或其层级没有开启 accounting 时,表格可能出现空白或不完整数据。因此看到内存或 I/O 列没有数值,先不要把它解释成“占用为零”。

可以先读取 unit 的 accounting 配置,再决定是否需要修改配置。下面的命令是读取和定位配置的示例;是否开启 accounting 需要结合主机策略评估,不能为了临时观察直接在生产主机上无计划改动。

# 读取目标服务当前的资源 accounting 属性
systemctl show example.service \
  -p MemoryAccounting \
  -p IOAccounting \
  -p CPUAccounting \
  -p TasksAccounting

# 查看 unit 最终合并后的配置来源,便于找到 drop-in 覆盖项
systemctl cat example.service

MemoryAccounting=yes负责打开该 unit 的内存 accounting,IOAccounting=yes负责块设备 I/O accounting;它们会按照 cgroup 层级产生相应的影响。修改配置后要重新加载 unit,再安排服务重启或按变更策略生效,不能把一次查询结果当成配置已经更新。

为什么 CPU 百分比会超过 100%

在systemd-cgtop中,CPU 负载值按处理器数量累计。四个逻辑处理器的主机上,理论显示范围可以到 400%;因此看到 180% 并不矛盾,它表示大约占用了 1.8 个处理器的计算时间。若需要看累计时间而不是百分比,可以使用--cpu=time或在交互界面按%切换。

这里要把“资源比例”和“服务是否异常”分开判断:高 CPU 只说明当前 cgroup 使用了较多 CPU,还需要结合请求量、线程数、日志和业务延迟判断原因。systemd-cgtop 能帮你找到观察入口,但不会替代应用级 profiling。

导出有限次采样,结束后再做复盘

如果要把几次实时结果交给另一个命令或临时保存到文件,可以使用批处理模式。非 TTY 场景下工具本来也倾向于单次迭代,明确写出--batch和--iterations会让采样边界更清楚。

# 非交互采样 5 次,每次间隔 1 秒,按 CPU 排序
systemd-cgtop --batch --iterations=5 --delay=1s --order=cpu

# 使用原始数字格式,便于后续脚本接收字节数和时间值
systemd-cgtop --batch --iterations=3 --raw --order=memory

批处理输出适合回答“刚才这几秒谁最突出”,不适合回答“过去一天谁持续占用最高”。后一个问题需要历史指标系统或日志化采集;不要通过无限追加终端文本,制造一个难以检索的伪监控。

systemd-cgtop 的实时采样、accounting 配置、排序参数和复查对象之间的静态关系图
图2:实时采样与 accounting、排序、层级深度和复查边界的静态关系说明图,不是实际运行结果。

现场排查可以固定成这张清单

现象先看什么解释边界
CPU 第一名很高--order=cpu、服务层级、线程数CPU 百分比可超过 100%,先按主机处理器数量理解
内存列没有数值MemoryAccounting与 memory controller空白不等于零,可能是 accounting 未启用
I/O 列没有数值IOAccounting与 io controller先确认统计口径和存储路径,不直接下结论
输出行太多--depth或服务 cgroup 路径缩小观察范围,不要先改资源限制
需要交给脚本处理--batch、--iterations、--raw这是有限实时采样,不是历史监控

常见问题

systemd-cgtop 能替代 top 吗?

不能完全替代。top更偏向单进程和线程视角,systemd-cgtop更偏向 systemd 管理的 cgroup 归属。排查服务整体资源占用时用后者更直接,追单个 PID 时仍需要进程级工具。

为什么 systemd-cgtop 只显示一条结果就退出?

如果标准输出不是 TTY,工具会采用适合脚本的非交互行为,默认只运行一次;需要多次采样时显式指定--iterations,并配合--batch。

只看服务资源时应该先调哪个参数?

先用服务对应的 cgroup 路径或--depth缩小层级,再用--order选择资源列。这样能减少层级噪声,也不会改变服务本身的资源策略。

总结一下:systemd-cgtop最适合做“当前现场的 cgroup 资源定位”。先按 CPU、内存和 I/O 分别观察,再检查 accounting/controller 是否提供了完整数据;遇到多核 CPU 百分比时按处理器总数理解,最后用有限次 batch 采样留下复查材料。它告诉你现在谁更突出,但不会替你保存长期趋势或解释业务根因。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>