Linux 服务器 CPU 飙高排查实战:从 top 到火焰图

举报
小原100 发表于 2026/10/25 10:46:37 2026/10/25
【摘要】 一次 CPU 飙高告警的完整排查复盘:用 top 分清 us/sy/wa 三种消耗方向,pidstat 下钻线程,strace 判断阻塞,perf 火焰图定位代码热点,最后沉淀成可复用的排查决策树。

一、先看全局:top 的三行关键信息

登录服务器第一件事不是急着重启进程,而是花 30 秒看清全局。第一行 load average 的三个数值分别代表 1、5、15 分钟负载,经验判断标准是单核负载持续超过 0.7 就值得关注。第三行 %Cpu(s) 里的四个字段含义必须分清:

%Cpu(s): 85.3 us,  8.1 sy,  0.0 ni,  0.0 id,  6.2 wa,  0.1 hi,  0.3 si

us 高说明是用户态业务代码在消耗 CPU;sy 高意味着内核态繁忙,常见于海量系统调用或频繁上下文切换;wa 高则是 IO 等待,CPU 其实在“闲着等磁盘”,优化方向完全不同;si 高要怀疑软中断,典型场景是网卡流量打满。按大写 P 键以 CPU 占用排序,记下嫌疑进程的 PID。

二、线程级定位:pidstat

top 默认只展示进程维度,多线程程序需要下钻到线程。pidstat 加 -t 参数按 1 秒间隔输出线程级数据,能直接看到哪个 TID 在燃烧 CPU:

pidstat -t -p $(pidof java) 1 5
# 拿到热点 TID 后转 16 进制供 jstack 使用:
printf '%x\n' 12345

对 Java 服务,把热点 TID 转 16 进制后在 jstack 输出里搜索 nid=0x3039 即可锁定具体线程栈,这一步通常能直接定位到业务代码行。

三、判断阻塞还是计算:strace

如果进程 CPU 高但逻辑上看不出在忙什么,用 strace 统计系统调用分布,-c 汇总模式比逐行跟踪直观得多:

strace -c -f -p 12345
# 关注 calls 列异常多的调用与 errors 列:
strace -T -e trace=network -p 12345 2>&1 | head -50

若 errors 列出现大量 ENOENT 或 EAGAIN,多半是代码在疯狂重试;若 futex 调用占比极高,则是锁竞争,方向应转向并发逻辑审查而不是加机器。

四、终极手段:perf 火焰图

常规工具都解决不了时,perf 采样加火焰图能给出函数级答案:

perf record -F 99 -p 12345 -g -- sleep 30
perf script | stackcollapse-perf.pl | flamegraph.pl > cpu.svg

火焰图中横向越宽的函数占用 CPU 越多,热点路径一眼可见。采样频率选 99Hz 是刻意避开与其他周期性活动产生共振。

五、沉淀成决策树

整个排查可以固化成一条路径:top 看 us/sy/wa 定方向,pidstat 下钻线程,计算型问题走 perf 火焰图,阻塞型问题走 strace,Java 程序优先用 jstack 对热点 TID。多数 CPU 告警在前两步就能收敛,真正的功夫在于把每个工具的输出和“用户态、内核态、IO 等待”三种 CPU 消耗模型对应起来,避免南辕北辙。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。