Linux 服务器 CPU 占用飙高:从 top 到定位代码的排查思路

举报
yd_283936595 发表于 2026/11/05 10:21:49 2026/11/05
【摘要】 从 load 与 us/sy/wa 判断方向,用 top -Hp 定位线程,再借助 jstack、py-spy、perf 定位热点代码,并总结常见原因与预防措施。

一、先判断现象:是真忙还是假忙

收到 CPU 告警后,不要急着杀进程。先执行 uptime 看 load average,再用 top 看 CPU 行各项占比:

  • us 高:用户态计算多,多是业务代码热点、死循环、正则回溯。
  • sy 高:内核态开销大,常见于频繁系统调用、上下文切换、锁竞争。
  • wa 高:在等磁盘或网络 IO,CPU 并不忙,应转去查 iostat。
  • si 高:软中断多,常见于网卡小包风暴,可看 /proc/softirqs。

load 高而 CPU 不高,多半是 IO 等待或线程排队,思路完全不同。

二、找到进程和线程

top -c            # 按 P 按 CPU 排序
top -Hp <pid>     # 查看该进程内各线程的 CPU 占用

记下最耗 CPU 的线程号(TID),按 1 可查看每个核心,判断是单核打满还是整体饱和。

三、把线程号映射到代码

Java:线程号转 16 进制,在 jstack 输出中匹配 nid。

printf '%x\n' 12345        # 得到 3039
jstack <pid> | grep -A 20 'nid=0x3039'

连续抓三次 jstack 对比,反复出现在同一方法栈的就是热点。若线程名是 GC task thread,说明 GC 频繁,应看 jstat -gcutil。

Python:py-spy dump --pid <pid>,无需重启即可看调用栈。

C/C++:perf top -p <pid> 采样查看热点函数。

四、常见原因

  1. 死循环或空转:条件写错,或无退避的重试循环。
  2. GC 频繁:内存泄漏或堆过小,Full GC 反复触发。
  3. 正则回溯:嵌套量词遇到特殊输入,耗时指数增长。
  4. 锁竞争:线程频繁切换,sy 与上下文切换同时升高,可用 pidstat -w 确认。
  5. 软中断:网络包集中在单核,需开启 RPS/RSS 分散,或排查异常流量。

五、处理与预防

止血:先限流、降级或摘除异常节点,保留现场(jstack、火焰图)后再重启。

根治:修复热点代码,给正则和循环加超时与上限,为线程池和队列设边界。

预防:

  • 监控告警:对 CPU 占比、load、GC 次数、线程数设置分级告警。
  • 常态化压测:上线前压测,提前暴露热点和锁竞争。
  • 灰度发布:新版本先小流量观察,异常即回滚。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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