news 2026/10/4 18:54:18

服务器CPU使用率过高怎么排查?从 top 到火焰图,一次定位吃 CPU 的进程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
服务器CPU使用率过高怎么排查?从 top 到火焰图,一次定位吃 CPU 的进程

凌晨两点收到告警,登录上去第一反应往往是top一把梭,看到 %Cpu 飙红就准备重启。先别急。服务器CPU 到底是被谁吃满了、是真算力不够还是被 IO 拖累,这两件事的处理方式完全不同,分不清就重启,大概率半小时后又告警。

这篇文章把"CPU 打满"这件事拆成四步:先定性,再定位进程,再钻到进程内部,最后才是止血还是扩容。每一步都给可照做的命令,也标出几个容易误判的坑。

一、先定性:你看到的"CPU 高"到底是哪一种

top第一行那行%Cpu(s)是整台机器最该先看懂的地方,它把时间切成了八块:

  • us:用户态时间,应用代码在跑,大部分 CPU 消耗落在这里
  • sy:系统态时间,内核在干活(系统调用、中断、调度)
  • ni:被降过优先级的进程占的时间
  • id:完全空闲
  • wa:iowait,CPU 其实闲着,在等磁盘或网络 IO 完成
  • hi/si:硬件 / 软件中断
  • st:steal time,只出现在虚拟机里,是宿主机把本该给你的 CPU 周期给了别的租户

关键判断就三条:

  1. us高、id低 → 应用真的在吃算力,往下走"定位进程"那条线。
  2. wa高、us低 → 不是 CPU 的锅,是存储或网络 IO 瓶颈,top里%wa冒红就别去加 CPU,先查磁盘和慢查询。
  3. st高 → 你是虚拟机且宿主机超卖了,本地再怎么调优也绕不开这层限制,只能找厂商换规格或换宿主机。

还有一个常被误读的指标:load average(平均负载)。它显示的三个数(1 分钟 / 5 分钟 / 15 分钟)统计的是"可运行态(R)+ 不可中断睡眠态(D)"的进程数,D 状态基本就是卡在 IO 上的进程。所以一台机器 load 飙到 20、但%Cpu的id还有 70%,很可能只是磁盘慢,CPU 自己闲着。判断 CPU 是否真饱和,别只看 load,要看vmstat 1的输出:

vmstat1# procs ---- r b ---- cpu --- us sy id wa st# r b swpd free buff cache si so bi bo in cs us sy id wa st# 8 2 0 120000 0 800000 0 0 40 120 300 900 85 5 2 5 3

r是运行队列长度,b是卡在 D 状态的进程数,us/sy/id/wa/st对应上面那八块。对照nproc出来的核数——r长期大于核数才是真的排队等 CPU,b长期很大则是 IO 在堵。

一个真实的误判案例:某次告警 load 冲到 15,新人直接申请扩容,结果top里%id还有 60%、%wa到了 35%——根因是一块云盘 IO 被打满,MySQL 在等磁盘,CPU 根本没饱和。机器加上去,IO 还是瓶颈,问题照旧。这就是为什么要先看完那八个数再决定动作。

还有一层容易坑人的是容器。在 Docker / K8s 容器里直接跑top或nproc,经常看到的是宿主机的核数,而不是这个容器被分配到的限额。要看容器真正能用多少 CPU,得读 cgroup 的配额文件/sys/fs/cgroup/cpu/cpu.cfs_quota_us和cpu.cfs_period_us,两者相除才是该容器允许使用的核数。监控指标也要以容器内采集的为准,否则你会以为 CPU 很闲,其实早被隔壁容器挤占了。

顺带提一句服务器cpu温度:如果机房空调出问题或风扇故障,CPU 会因为过热降频(thermal throttle),表现出来就是"没干重活却变慢",这种用sensors或带外管理的温度接口能看到,属于另一种独立的排查线,别和算力瓶颈混为一谈。

二、定位进程:top、htop 与 pidstat

定性完了,确认是us真高,下一步把"谁在吃"揪出来。

top默认就按%CPU从高到低排,进去后按P可以再强制按 CPU 排一次确认;htop更直观,按F6选CPU%排序,还能看到每个核的占用条。找到可疑 PID 后,光看%CPU不够,还要看它是单线程打满一个核(总利用率不高但那个核 100%),还是多线程铺满所有核。

要看每核明细,用mpstat -P ALL 1(来自 sysstat 包),单核 100%、其他核闲着,说明程序没做好并行,加核没用,得改代码或加进程数。

想要更干净的进程级采样,用pidstat:

pidstat-u1# 每 1 秒刷新各进程 CPU 占用pidstat-u-p12341# 只盯某个 PID

pidstat的好处是能跨采样窗口稳定输出,方便你贴进值班记录。顺带提一句,linux服务器查看cpu使用率和 linux服务器cpu使用率查看命令,网上搜出来大多是top/htop/mpstat这三板斧,记住它们各管一层就够了。想知道整机规模,如何查看服务器的内存和cpu参数可以从nproc和lscpu入手,前者看在线逻辑核数,后者看架构、型号和缓存。

三、钻进进程内部:不同语言各有各的刀

锁定到 PID 只是半路,真正要知道"它在算什么"得再往里钻,否则你只知道"MySQL 很忙",不知道它在跑哪条烂 SQL。

  • Java 服务:最省事的是 async-profiler,挂上就能采 CPU 火焰图:

    ./profiler.sh start<pid># 跑个几十秒./profiler.sh stop-fflamegraph.svg<pid>

    打开 svg,横着最宽的那一层函数,就是吃 CPU 的大头,照着去优化那一段比盲猜强十倍。

  • C / C++ / 系统层:perf top直接看实时热点函数;要留档就用perf record -F 99 -p <pid> -g -- sleep 30再perf report,不需要改代码、不需要重启。

  • MySQL:SHOW PROCESSLIST;看Time、State、Info三列,Time 很大且 State 卡在Sending data或Locked的,基本就是慢查询或锁等待,再去翻慢查询日志(slow log)拿完整 SQL。

  • PHP-FPM:开slowlog,超时的请求会把调用栈写进去,常见于某段同步远程调用或正则回溯爆炸。

  • Java 退出也有讲究:顺带说一句止血。对 JVM 这类进程,优先发kill -15而不是-9——-15会触发 shutdown hook,让连接池、线程池有序关闭、把内存里的数据刷盘;-9是直接剥夺进程,没机会做清理,重启后可能要更长的时间做恢复或校验。

  • 通用兜底:strace -p <pid> -c统计这个进程在调哪些系统调用,如果满屏是futex多半是锁竞争,满屏是read/write多半是 IO。

这一层的意义在于:服务器cpu使用率过高怎么解决,答案从来不在"重启"或"加机器",而在"到底是哪一行代码 / 哪一条 SQL"。定位不到这一层,扩容只是把问题变得更贵。

四、止血与根治:kill -9 不是万能药

临时要保住线上,有几招比直接杀进程温和:

  • renice +10 -p <pid>把问题进程优先级调低,让它少抢 CPU,给核心业务让路。

  • 用 systemd 的CPUQuota=或 cgroup 给这个服务设 CPU 上限,防止它把整台机器拖死:

    # /etc/systemd/system/xxx.service.d/limit.conf [Service] CPUQuota=50%
  • 业务侧限流、降级非核心功能,把峰值削平。

至于kill -9,有两个坑必须知道:一是D 状态(不可中断睡眠)的进程kill -9也杀不掉,因为它在等硬件事件(比如一块卡死的 nfs 挂载),得先解决底层 IO;二是数据库、消息队列这类有状态的进程,强杀主进程可能导致数据不一致或恢复缓慢,能kill -15(SIGTERM)让它自己收尾就别用-9。

根治的方向就三类:算法或 SQL 优化、加缓存减少重复计算、把同步改成异步或分片。止血能救今晚,根治才不用来回加班。

五、该扩容时怎么选 vCPU:云服务器的 4 核是真 4 核吗

前面都是"够不够用、哪里不够",如果确认就是长期算力不足,要加机器,这里有个选型章节值得单独说。很多人纠结"云服务器4核cpu是真4核还是假4核"——准确说,云服务器的 vCPU 一般是物理 CPU 的超线程切出来的逻辑核,且同一颗物理核由多个租户共享,这点从上面top里的%st(steal time)就能感觉到:邻居一忙,你的st就涨。所以它不是你独占的物理核,但对绝大多数业务来说,按 vCPU 数规划和按物理核规划在容量上是对等的,重点看的是:

  • vCPU 数量与基准性能 / 突发性能是否匹配你的常驻负载;
  • 突发型实例的CPU 积分机制(闲时攒、忙时花,持续高负载会"掉速");
  • 是否需要独享型 / 裸金属来规避超卖带来的st抖动。

各家实例规格的命名和 vCPU 映射都写在官方文档里,选型前建议直接翻三家对照,而不是只看某一家的宣传:

  • 阿里云 ECS 实例规格族说明:阿里云 ECS 实例规格
  • 腾讯云 CVM 实例规格:腾讯云 CVM 实例类型
  • 华为云 ECS 实例规格:华为云 ECS 实例规格

三家虽然命名不同(阿里云叫"实例规格族"、腾讯云叫"实例类型"、华为云也叫"实例规格"),但底层都是把物理 CPU 通过虚拟化切分成 vCPU 提供给租户。选购时真正要对比的是"这台实例能给到多少稳定算力"和对应的计费模型,而不是名字好不好听。突发型适合平时闲、偶尔冲一波的业务;独享型 / 裸金属适合对st抖动零容忍的稳态负载。

如果业务是短时、波峰波谷明显,弹性伸缩比租一台固定的 cpu服务器 更划算;如果是稳态高负载且对st敏感,独享型或裸金属更稳。另外别把 gpu服务器与cpu服务器的区别 搞混:普通 Web、数据库靠的是 CPU 通用算力,只有 AI 推理、训练、图像渲染这类并行计算才需要 GPU,两者选型维度不同,别一上来就堆 GPU。

六、收个尾

CPU 打满这件事,链路其实很清晰:先定性(us / wa / st 分清),再定位进程(top / pidstat / mpstat),再钻进程内部(火焰图 / 慢查询 / slowlog),最后才是止血或扩容。把这套走完,你解决的就不只是"这次为什么慢",而是真的知道瓶颈长什么样。

文中涉及的各家实例规格、vCPU 映射、计费与配额政策以厂商当期官方公示为准,扩容前请到对应控制台核实当期配置与价格,再决定是弹性扩容还是换独享规格。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 18:53:50

基因组重复序列注释全流程:RepeatModeler建库与RepeatMasker屏蔽实操

基因组组装完成后&#xff0c;跑完三代组装、Hi-C挂载、纠错这些大工程&#xff0c;很多人会下意识松一口气——但如果你直接把基因组丢给BRAKER或者Augustus做基因结构预测&#xff0c;接下来大概率会收获一堆结构错乱的基因模型。这不是组装的问题&#xff0c;而是绕过了重复…

作者头像 李华
网站建设 2026/10/4 18:47:53

嵌入式I2C驱动开发实战:从协议原理到Linux内核与调试避坑

1. I2C 驱动开发&#xff1a;从协议原理到实战落地搞嵌入式这行十来年&#xff0c;I2C 是我见过最“磨人”也最“离不开”的总线。你说它慢吧&#xff0c;400kHz 的标准模式确实跑不过 SPI 的几十兆&#xff1b;你说它简单吧&#xff0c;两根线挂几十个设备&#xff0c;地址冲突…

作者头像 李华
网站建设 2026/10/4 18:44:34

理解界面陷阱电荷与费米钉扎效应:提升功率半导体可靠性的关键

1. 界面陷阱电荷&#xff1a;从一张C-V曲线说起做功率半导体器件的工程师&#xff0c;尤其是跟SiC MOSFET、GaN HEMT 打交道久了&#xff0c;一定绕不开一个现象&#xff1a;实测的阈值电压和理论算出来的对不上&#xff0c;或者干脆飘得离谱。我做SiC MOSFET可靠性测试那几年&…

作者头像 李华
网站建设 2026/10/4 18:42:42

企业微信外部群成员移除:私域社群秩序与合规管理指南

很多做私域的人&#xff0c;一开始都盯着“怎么把客户拉进群”&#xff0c;却很少想过“怎么把不该在群里的人请出去”。我最早带社群项目时也是这样&#xff0c;几百个群里塞满了一堆人&#xff0c;看起来热闹&#xff0c;实际上广告、诈骗链接、同行截流号混在一起&#xff0…

作者头像 李华