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 是三个不同的线索,排序方式不同,得到的第一名也可能不同。

用一次基础观察确定资源方向
直接执行下面的命令可以打开交互式观察界面。命令本身只读取实时统计,不会改变服务配置;退出时使用 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
批处理输出适合回答“刚才这几秒谁最突出”,不适合回答“过去一天谁持续占用最高”。后一个问题需要历史指标系统或日志化采集;不要通过无限追加终端文本,制造一个难以检索的伪监控。

现场排查可以固定成这张清单
| 现象 | 先看什么 | 解释边界 |
|---|---|---|
| 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 采样留下复查材料。它告诉你现在谁更突出,但不会替你保存长期趋势或解释业务根因。
-
432 收藏
-
273 收藏
-
文章 · linux | 1个月前 | 内存 · Linux · 运维排查 · Linux OOM cgroup v2 memory.events memory.current memory.max memory.high456 收藏
-
462 收藏
-
252 收藏
-
214 收藏
-
207 收藏
-
356 收藏
-
320 收藏
-
327 收藏
-
449 收藏
-
360 收藏
-
415 收藏
-
199 收藏
-
367 收藏
-
399 收藏
-
290 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习