文章詳情

阿里雲國際帳號 阿裡雲 ECS CPU 飆升 100% 怎麼辦?Linux 進程排查與應急降載處理

阿里雲國際2026-08-01 15:13:58雲計算

先判断:100% 不一定等于“机器死了”

阿里云 ECS 的 CPU 飙到 100%,最容易犯的错就是看到告警就立刻重启。重启有时能暂时把问题压下去,但也可能把真正的线索一并抹掉。正确的顺序不是“先处理结果”,而是“先确认现象,再找原因,最后做降载”。CPU 100% 只是表象,背后可能是某个 Java 线程死循环、某个 Python 进程疯狂计算、某个日志任务把磁盘和 CPU 一起拖住,也可能是软中断、内核态开销、流量突增、定时任务集中触发,甚至是容器资源配额不合理。

第一步要分清楚,究竟是“单核打满”还是“整机算满”。在多核 ECS 上,单个进程显示 100% 并不奇怪,因为那往往只代表占满了一颗核心;如果一台 4 核机器上有多个线程同时跑满,进程 CPU 可能显示 300%、400%,这才是更危险的信号。另一个常见误区是把 load average 和 CPU 使用率混为一谈。load 高不一定是 CPU 算不过来,也可能是大量进程在等磁盘、锁、网络或内核资源。排查时要把用户态、系统态、iowait、steal 这些指标一起看,不能只盯着 top 里的那一列数字。

第一轮排查:先看全局,再看局部

真正的应急排查,前 3 分钟最重要。不要急着登录面板点重启,也不要先去翻代码。先在 ECS 上把全局状态摸清楚,确认是不是整机异常、是不是流量突然冲高、是不是某个进程长时间占用 CPU。推荐先看这几条命令,它们足够快,也足够直接。

uptime
vmstat 1
mpstat -P ALL 1
top -c

uptime 能快速看出系统负载,vmstat 1 能看到运行队列、上下文切换和 CPU 分布,mpstat -P ALL 1 可以观察每颗核心的忙闲情况,top -c 则能把占用最高的进程按 CPU 排出来。这里有个很实用的判断方法:如果 us 很高,通常是用户态代码在跑;如果 sy 很高,说明内核态开销大,可能是频繁系统调用、网络包处理、锁竞争;如果 wa 很高,问题未必在 CPU,而更像磁盘 I/O 卡住;如果 st 异常高,在云主机上还要留意宿主机资源争用。

同时别忘了看阿里云控制台里的监控曲线。ECS 本身的 CPU、内存、网卡、磁盘、进程数、负载,如果在云监控里有完整历史,就很容易把“单点爆发”与“持续爬升”区分开。前者多半是临时流量、批处理任务或异常线程,后者则更像代码泄漏、线程积压、缓存击穿、队列堆积。判断趋势很关键,因为它决定了你是先做降载,还是先直接止血。

定位进程:从进程到线程,一层层缩小范围

CPU 飙高时,真正的罪魁祸首往往不是“应用本身”,而是应用里的某个进程、线程,甚至某个定时任务。先用 ps 找到最占 CPU 的进程,再进到线程层面查细节,是最稳的办法。

ps -eo pid,ppid,tid,pcpu,pmem,stat,cmd --sort=-pcpu | head -20
top -H -p 1234
pidstat -u -p 1234 1

ps 的好处是结果稳定、适合留档;top -H -p 适合快速看某个进程内部到底是哪条线程在烧 CPU;pidstat 则能连续观察某个 PID 的变化,适合判断是否“间歇性飙高”。如果你看到 Java 进程长期占满 CPU,可以继续往下看线程名和线程 ID,配合 JVM 的线程栈去查。对于 Go、Python、Node.js 这类语言,也要看是解释器层面的循环,还是某个原生库函数在忙等。

当进程已经锁定后,下一步是判断它到底在干什么。最常见的几类原因有:无限循环、正则回溯爆炸、序列化或加密计算过重、批处理一次性放大、日志打印失控、线程池配置过大、锁竞争导致的空转。很多线上事故不是“程序不会跑”,而是“程序一直跑但跑错了方向”。如果是计算型业务,往往 CPU 是主角;如果是 I/O 型业务,CPU 高只是表象,真正的根因可能是重试风暴。

进一步深挖:别只看进程名

仅仅知道是哪个进程还不够。你需要知道它为什么忙。对于纯用户态高 CPU,可以用 perf top -p 1234 看热点函数,快速判断是某个算法、某个序列化框架,还是某个业务循环在反复执行。对于系统态偏高的场景,可以结合 strace 短时观察系统调用,看看是不是频繁打开文件、写日志、等待网络返回,或者被某个资源卡住后不断重试。

perf top -p 1234
strace -p 1234 -tt -f -s 80 -o /tmp/strace.log

不过要注意,straceperf 都会带来额外开销,生产环境要短时间使用,目标是取证,不是长期挂着跑。真正成熟的做法,是在平时就把火焰图、指标埋点、慢调用日志、GC 日志、线程池监控、队列长度监控准备好。这样一旦 CPU 异常,排查路径会短很多,而不是只能靠猜。

常见根因:为什么 ECS 会突然被打满

CPU 飙升不是一个原因,而是一组模式。第一类是业务代码本身出了问题,比如死循环、递归过深、热点数据结构退化、排序或匹配复杂度突然放大。第二类是流量型问题,接口请求量短时间暴涨,线程池和队列都被打满,CPU 只是承接压力的最后一环。第三类是依赖型问题,数据库、缓存、消息队列响应变慢,应用进入重试和超时循环,最后把 CPU、连接池、线程池一起拖垮。

第四类经常被忽略,是系统层面的异常。比如软中断高、网络包转发异常、日志刷盘频繁、容器 cgroup 配额过紧、虚机上其他资源争抢、定时任务和备份任务集中触发。特别是在 ECS 上,如果同一时间有多个实例同时做压缩、同步、扫描、清理,CPU 和磁盘会一起告急。这种问题最容易被误判成“应用代码坏了”,实际上只是系统调度把你推到了临界点。

还有一种情况是“看起来像 CPU 高,其实是业务在等”。比如数据库慢查询导致线程长时间阻塞,线程池中的线程不断被唤醒又阻塞,最终形成高频切换和空转;或者缓存雪崩时,大量请求打到后端,应用层不断做重试与降级,最后把 CPU 消耗在无效循环上。此时你如果只盯进程名,很容易误判方向,真正应该看的,是请求链路、依赖延迟和队列积压。

应急降载:先让系统喘口气

当你确认 CPU 已经影响到线上服务,目标就不再是“立刻根治”,而是“先把损失压住”。应急降载的核心原则只有一个:优先保核心链路,主动切掉非核心负载。最常见的做法,是先把实例从负载均衡里摘掉,或者把流量权重调低,避免新的请求继续涌入。若是有开关控制、灰度发布、限流规则、降级策略,应该优先启用,而不是等应用自己扛住。

如果是某个后台任务把 CPU 拉满,比如报表生成、索引重建、批量导入、日志压缩、数据同步,可以直接暂停或降低并发。能停就先停,能改成低峰跑就先改。对于消费消息的服务,也可以先降低消费速度,或者临时暂停非核心主题,避免积压消息继续把机器推向高位。很多时候,停掉一条“非关键但很耗 CPU”的任务,效果比盲目扩容更快。

进程级别也可以做临时控制。比如把抢占资源的进程调低优先级,避免它继续和主链路争 CPU;如果某个任务已经明显异常,可以先尝试平滑停止,再视情况重启。极端情况下,kill -STOP 可以先冻结进程,争取时间做取证,但这需要非常清楚它对业务的影响,不能随手乱用。对于运行在容器里的服务,除了看宿主机 CPU,还要看容器配额、限额和线程数,否则你以为是机器满了,实际可能只是单容器被卡死。

renice 10 -p 1234
systemctl stop xxx
kill -TERM 1234

这里要强调一点:不要一上来就 kill -9。强杀虽然快,但会丢日志、丢现场、丢缓存状态,甚至把数据文件写到一半,造成后续更难排查的二次事故。能正常退出就正常退出,能先记录现场就先记录现场。生产应急不是比谁手快,而是比谁能在最短时间内把问题范围收住。

降载的实际顺序

阿里雲國際帳號 更稳妥的顺序通常是:先降流量,再停非核心任务,再限并发,最后才考虑重启。因为流量一旦不再进入,CPU 往往会自然回落;如果请求仍然在灌,重启只是把机器从“满载”变成“冷启动后再次满载”。如果是数据库、缓存、消息队列依赖慢,重启也许还会引发连接重建、缓存击穿和更多连锁反应。真正有效的降载,应该同时盯住入口和出口。

不要只会重启:应急后的取证和复盘

很多团队的习惯是,CPU 一高就重启,重启完恢复了就当没事发生。这样看似省事,实际上最容易把事故变成重复事故。正确做法是,在恢复服务前,把必要的信息都留住:当前负载、top 输出、ps 列表、线程栈、系统日志、应用日志、最近发布记录、定时任务记录、云监控截图。这些东西不是给当天看的,而是给下一次避免踩坑用的。

复盘时不要只问“是谁改了代码”,更要问“为什么上线前没发现”“为什么预警没提前触发”“为什么降级开关没有准备好”。如果 CPU 飙高是由某个接口引起,就要检查这个接口有没有限流、熔断、超时和缓存;如果是批处理任务引起,就要检查调度窗口、并发数、数据量上限和失败重试策略;如果是依赖变慢引起,就要检查调用超时是否合理、重试是否过多、熔断是否生效。

还应该把“事故处理顺序”标准化。最起码要写清楚:先看什么命令,先找哪个进程,哪种情况下摘流,哪种情况下停任务,哪种情况下可以重启,谁负责对外通知,谁负责记录现场。没有流程的团队,遇到 CPU 100% 时容易每个人都很忙,却没有人真正把问题往前推进一步。流程不是形式,而是把混乱变成可重复动作的工具。

平时怎么预防:让 100% 不再成为惊喜

真正成熟的做法,是把“CPU 飙升”变成一个可预案、可预警、可回滚的事件,而不是现场救火。第一,监控要细,不只看整机 CPU,还要看进程级 CPU、线程数、load average、iowait、系统态占比、上下文切换、容器配额和请求延迟。第二,告警要分层,普通抖动和持续高位要分开,短时尖峰和持续爬升也要分开,不然告警会把人烦到麻木。

第三,发布要保守。高风险变更最好做灰度,至少要能快速回滚。第四,任务要隔离,把在线服务、离线任务、定时作业尽量分开,不要都堆在一台 ECS 上。第五,容量要留余量。很多故障不是因为程序突然变坏,而是系统本来就跑在 70% 到 80% 的高位,任何一个小波动都会把它顶爆。留出缓冲,才有容错空间。

阿里雲國際帳號 最后,建议给团队准备一份简短但实用的应急手册。里面只写三类内容:常用命令、降载动作、回滚路径。手册不需要写成论文,但一定要放在大家找得到的地方。等 CPU 真正飙起来的时候,最值钱的不是聪明,而是第一时间知道下一步该做什么。

结语

阿里云 ECS 的 CPU 飙到 100%,看起来像一个数字问题,实际是一次系统协作能力的考试。会不会排查进程,能不能判断是用户态还是内核态,能不能在不丢现场的前提下降载,决定了你是把事故压住,还是把事故放大。记住,先定位,再降载,后修复,最后复盘。把这套顺序做熟,CPU 100% 就不再是恐慌的开始,而只是一个可控的故障信号。

Telegram售前客服
客服ID
@cloudcup
联系
Telegram售后客服
客服ID
@yanhuacloud
联系