定位 Linux「CPU 突然飙高」的四步排查法

举报
yd_213494201 发表于 2026/10/27 06:19:40 2026/10/27
【摘要】 从 top、pidstat 到 jstack 与 perf,一套可复用的 Linux CPU 飙高定位路径,以及容器核数、GC 线程、符号缺失三个常见误判。

凌晨两点收到「接口变慢」的告警,登上去一看 load 12。这种时候最怕两种反应:一是直接重启,二是凭感觉改代码。CPU 飙高的定位其实有固定套路,四步就能把范围从「整台机器」收窄到「某一行代码」。

第一步:确认是真的忙,还是被平均了

先看 top -b -n1 | head -20 里的 us / sy / wa。us 高是用户态在算,sy 高多半是系统调用或中断,wa 高说明根本是 I/O 在拖,CPU 背了锅。

再用 mpstat -P ALL 1 5 看每颗核。只有一颗核 100%、其余闲着,基本可以锁定单线程死循环;所有核一起飞,才是并发任务或流量上涨。

第二步:锁定进程

pidstat -u 1 5 按 %CPU 排序,把嫌疑进程挑出来。顺手看一眼 %usr 和 %sys 的比例:一个 Java 服务 %sys 长期偏高,通常是日志刷盘或大量小对象触发的系统调用,而不是业务计算。

第三步:从进程缩到线程

top -H -p <pid>,或者 ps -L -o tid,pcpu,comm -p <pid> --sort=-pcpu | head。拿到线程号后转十六进制:printf '0x%x\n' <tid>,再去 Java 线程栈里搜 nid=0x...,就能把 CPU 最高的线程和一个具体方法对上。

取栈优先用 jcmd <pid> Thread.print,它比 jstack -F 温和。生产环境连续取三次、间隔 5 秒,三次都停在同一处的才是热点,只出现一次的是瞬时抖动。

第四步:采样看热点函数

perf top -p <pid> 实时看,或者 perf record -F 99 -g -p <pid> -- sleep 30 采样 30 秒,再 perf report 看调用链。火焰图上那段又宽又平的栈,就是答案。

三个容易误判的坑

一是容器里的核数。top 显示的是宿主机核数,%CPU 能超过 100%,先查 cgroup 配额再判断有没有「跑满」。二是 GC 线程。%CPU 高、业务线程栈却都空闲,八成是 GC 在刷,直接 jstat -gcutil <pid> 1000。三是符号缺失。perf 只显示十六进制地址时,检查 /proc/sys/kernel/perf_event_paranoid 是否大于 2,以及二进制有没有带调试符号。

把它变成一条命令

这四步每次手敲太慢,写成脚本把 top 快照、pidstat、线程栈、perf record 一起落到 /tmp/cpu-YYYYmmdd-HHMM/ 下,事后复盘和定位都有依据。

定位问题的价值不在于找到凶手,而在于让下一次不用再找:把采集脚本和判定阈值沉淀下来,告警响起时人只做决策,不做体力活。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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