美国服务器CPU持续高负载时,如何结合进程、内存与磁盘I/O定位原因

先分清“CPU高”与“机器忙”
美国服务器的 CPU 使用率持续偏高,不一定代表程序在做大量计算。Linux 的负载均值还会计入处于不可中断等待状态的任务;磁盘 I/O 堵塞时,负载均值可能上升,但 CPU 并没有被计算任务持续占满。反过来,单个进程显示高 CPU,也不一定说明整台服务器已达到容量上限。
排查时应把同一时间段内的 CPU、进程状态、内存、I/O 和连接数放在一起看。先用只读命令记录现状,再根据指标之间的关系缩小范围;不要仅凭一次采样就重启服务或结束进程。以下命令适用于常见 Linux 系统,部分工具需预先安装,执行时通常不需要修改系统配置。
先采集同一时段的指标
date
uptime
nproc
top -b -d 2 -n 5
vmstat 1 10
uptime 显示的负载均值是过去一段时间的平均值,不是 CPU 百分比;nproc 显示可用的处理器数量,可用于理解负载规模,但不能单独作为故障判据。top 适合观察 CPU 使用者和进程变化,vmstat 则能同时查看运行队列、内存交换、阻塞任务和 I/O 等待。
注意,vmstat 输出的第一行通常是开机以来的平均值,后续行才是采样间隔内的变化。判断持续问题时,应关注后续多行是否稳定呈现相同趋势,而不是只看首行或某一瞬间。建议在负载出现时采样,也在业务正常时记录一份基线,避免把正常峰值误判为异常。
判断 CPU 是否真的被计算任务占满
在 top 中关注 CPU 各项占比,而不只是总使用率:
us偏高,通常表示用户态程序在消耗 CPU,应继续找具体进程或线程。sy偏高,表示内核态开销较多,可能与系统调用、网络包处理、文件系统操作或频繁的上下文切换有关。wa偏高,表示 CPU 时间中有较多部分用于等待 I/O;应继续检查磁盘和进程状态,不能直接归因于 CPU 算力不足。st偏高,表示虚拟机等待宿主机调度的时间。若该项持续异常,应结合虚拟化环境和服务商提供的监控信息核实,单靠客户机内的进程列表无法解释宿主机调度情况。
使用 sysstat 工具包中的 mpstat 可观察各逻辑 CPU 是否分布不均:
mpstat -P ALL 1 5
若只有部分核心繁忙,可能是单线程任务、线程亲和性或工作分配不均;若各核心都长期繁忙,才更像是并行任务持续占用。工具未安装时,不要据此推断指标为零,可先用 top 查看 CPU 行及进程情况。
找出 CPU 排名前列的进程:
ps -eo pid,ppid,stat,pcpu,pmem,rss,comm --sort=-pcpu | head
对可疑进程进一步查看线程和采样变化:
pidstat -u -r -d 1 5
top -H -p PID
将 PID 替换为实际进程号。pidstat 同样来自 sysstat;top -H 用于查看进程内线程,适合排查单个线程持续繁忙的情况。进程的 %CPU 在多核系统上可能超过 100%,因为不同工具的显示方式可能按单核或整机归一化;应结合 top 的显示模式、核心数量及连续采样理解,不要直接把单个进程的数值与整机百分比等同。
如果进程 CPU 高且运行状态以 R 为主,说明它处于运行或等待 CPU 调度状态;多个进程持续可运行,同时 CPU 使用率也高,通常指向计算任务或并发量增加。若 CPU 总体不高,但负载均值高,应优先检查 D 状态任务和 I/O 等待,而不是先扩充 CPU。
用内存指标判断是否存在回收或交换压力
先查看可用内存和交换活动:
free -h
vmstat 1 10
free 中的 available 比单看 free 更适合判断系统是否还有可用内存,因为 Linux 会将部分空闲内存用于缓存。缓存占用较多本身不等于内存不足。vmstat 中的 si、so 分别表示换入、换出活动;若在持续采样中反复出现,并与应用变慢、CPU 系统态升高或负载增加同时发生,才需要重点怀疑内存压力。单次数值不能证明正在发生严重交换。
找出常驻内存较大的进程:
ps -eo pid,ppid,stat,pmem,rss,comm --sort=-rss | head
RSS 是进程当前驻留在物理内存中的部分,不等于该进程独占的全部内存;共享库等页面可能被多个进程共享,不能把所有进程的 RSS 简单相加后当成整机实际用量。
若系统提供压力停滞信息,可读取:
cat /proc/pressure/memory
该文件不存在时,可能是内核或系统环境不支持,不能据此判断没有内存压力。内存可用量持续下降、交换活动持续发生,或内核日志出现内存不足相关记录时,应进一步核对进程增长、缓存行为和服务日志;不要仅因为内存占用率高就清理缓存或结束进程。
把磁盘 I/O 与进程状态对应起来
检查设备层面的 I/O:
iostat -xz 1 5
iostat 属于 sysstat 工具包。重点观察采样期间的读写活动、队列和等待时间是否与业务变慢同时出现。await 反映请求等待时间的综合情况;%util 可辅助观察设备忙碌程度,但不能脱离设备类型和存储实现单独解释。多队列设备、RAID、虚拟磁盘等场景下,单看 %util 不足以证明设备已经饱和。
再检查进程是否产生较多 I/O:
pidstat -d 1 5
如系统已安装 iotop,也可用它观察正在进行 I/O 的进程;工具未安装时无需为了排查而贸然在生产环境中安装。查看进程状态分布:
ps -eo stat= | awk '{print substr($1,1,1)}' | sort | uniq -c
常见状态中,R 表示运行或可运行,S 表示可中断睡眠,D 表示不可中断睡眠,Z 表示僵尸进程。D 状态常与 I/O 等待有关,但也可能涉及其他内核等待,不能单凭状态字母认定磁盘故障;应检查同一时段的 iostat、进程 I/O 和应用日志。僵尸进程通常已退出、等待父进程回收,本身一般不是持续消耗 CPU 的进程。
检查连接数,但不要把连接多当成原因
查看连接总体情况和 TCP 状态分布:
ss -s
ss -Htan | awk '{print $1}' | sort | uniq -c
ss -Htan state established | wc -l
需要把连接对应到进程时,可使用:
sudo ss -tpn
该输出可能包含客户端地址、端口和进程信息,不宜未经处理直接公开粘贴。不同 TCP 状态的连接数只能提供线索:连接增多可能伴随请求处理、连接建立或资源管理开销,也可能只是长连接保持较多;ESTABLISHED 数量本身不能证明 CPU 正被这些连接占满。应结合应用日志、请求量、进程 CPU 和连接变化是否同步来判断。
按指标组合定位原因
| 观测组合 | 优先怀疑方向 | 下一步验证 |
|---|---|---|
| CPU 用户态持续偏高,少数进程或线程突出 | 应用计算、任务积压或并发上升 | 连续查看进程和线程采样,并对照业务请求及任务日志 |
CPU 总体不高,但负载均值偏高,D 状态任务增加 | I/O 等待或其他不可中断等待 | 对照 iostat、进程 I/O 和系统日志 |
available 持续减少,交换活动反复出现 | 内存压力或进程内存增长 | 核对 RSS 趋势、内存压力信息及内核日志 |
| 磁盘等待、队列与业务延迟同时升高 | 存储路径或读写负载成为瓶颈 | 区分是哪个设备、哪个进程以及何种读写操作 |
| 连接数增加,同时某服务 CPU 和请求量上升 | 连接或请求负载可能触发资源消耗 | 对照连接状态、进程映射、请求日志和业务峰值 |
这些组合用于确定调查顺序,不是单项指标与根因的一一对应关系。例如,高 I/O 等待可能来自应用同步写入、日志增长或其他进程;同样,CPU 高也可能由频繁网络处理、锁竞争或内核开销引起。要形成结论,应在同一时间窗口内看到指标变化相互吻合,并通过进程、日志或业务请求数据确认。
验证处理效果与容量边界
定位到具体进程后,先确认它属于哪个服务、由什么任务触发,以及异常是否能与请求量或定时任务对应。不要仅凭一次采样直接执行强制结束或重启:这可能中断请求、丢失未写入的数据,或使问题很快重现。需要重启时,应由服务负责人确认影响范围,并按服务自身的维护流程操作。
处理后,在相近业务负载下重新采集相同指标,并与故障期间及正常基线比较。若 CPU、内存、I/O 等指标恢复,但业务延迟仍未改善,应检查应用排队、外部依赖和连接处理等环节;若指标只短暂恢复后再次恶化,则应继续追踪触发条件。
容量判断也应基于可重复的业务负载,而不是单次峰值。逐步增加实际请求或任务量,观察 CPU 是否持续饱和、运行队列是否增长、可用内存与交换活动是否恶化、I/O 等待是否上升,以及服务延迟是否随之变化。只有当多个相关指标在相同负载下稳定复现瓶颈,才能判断限制主要来自计算、内存还是存储;该结论仅适用于被测试的业务类型、并发方式和系统配置。