CPU 飙高 ≠ 服务器真的卡?

CPU 飙高 ≠ 服务器真的卡?

在 Linux 服务器运维中,相信很多人都遇到过这种情况:监控平台报警"CPU 使用率 95%+",登录服务器查看却发现服务响应正常,业务无感知;反之,偶尔 CPU 使用率仅 60%,业务却出现延迟、请求超时。

很多人默认"CPU 飙高 = 服务器卡顿",但实际上,CPU 使用率只是表象,真正决定服务器是否"卡顿"的是进程状态、IO 等待、资源竞争等核心指标。本文结合 Ansible 自动化批量排查案例、生产环境真实故障场景,从原理到实操,完整拆解 Linux 服务器 CPU 相关的卡顿排查全流程。

Linux 服务器卡顿故障排查实战指南

CPU 高 ≠ 卡顿

很多运维同学的排查第一步是 top,看到 CPU 低就放松警惕,看到 CPU 高就盲目杀进程。这是危险的习惯

维度 含义 核心影响
us(用户空间) 用户进程(业务程序、中间件)占用 CPU 时间 业务代码问题、高并发请求、内存泄漏导致的 CPU 空转
sy(系统空间) 内核态(进程调度、IO 调用、网络处理)占用 CPU 时间 系统调用频繁、进程切换过多、内核参数配置不当
wa(IO 等待) 进程等待 IO 完成(磁盘、网络、数据库)的 CPU 空闲时间 这是"假卡顿"的核心诱因!CPU 没干活,但进程在等 IO,看似 CPU 低,实则业务阻塞
hi/si(硬中断/软中断) 处理硬件中断(网卡、磁盘)、软中断(网络包、定时器)的时间 网络风暴、磁盘 IO 异常、中断队列积压
场景 CPU 表现 实际体验 原因
视频转码服务 90%+ 流畅 充分利用多核,IO 不阻塞
内存密集型应用 20% 极度卡顿 频繁换页,CPU 等待内存
磁盘 IO 阻塞 10% 命令无响应 进程处于 D 状态,不可中断睡眠
网络延迟 30% 接口超时 CPU 空闲等待网络 ACK

结论 :卡顿是体感指标 ,CPU 是资源指标。两者有关联,但绝非等价。


卡顿的原因是谁在等待?

Linux 下进程常见的状态决定了"卡"的根源:

bash 复制代码
# 查看进程状态
ps aux | awk '{print $8}' | sort | uniq -c | sort -rn
状态码 含义 卡顿关联
R 运行/就绪 正常,可能在抢 CPU
S 可中断睡眠 通常正常,等待事件
D 不可中断睡眠 🔴 高危!通常是 IO 阻塞
Z 僵尸进程 资源泄漏,需处理
T 停止状态 被信号暂停

大量 D 状态进程 = 系统级卡顿,CPU 再低也没用。


排查方法

确认"卡"的定义

先问三个问题:

  1. 谁卡? 单个应用 vs 整个系统 vs SSH 都连不上
  2. 什么操作卡? 特定接口 vs 所有操作 vs 仅写操作
  3. 何时开始? 突发 vs 渐进 vs 定时出现

💡 注意 :如果 SSH 登录都困难,优先检查内存和磁盘 IO,而非 CPU。


全局资源视图(别只看 CPU)

bash 复制代码
# 1. 综合资源监控(比 top 更全面)
vmstat -w 1 10

# 关键列解读:
# r: 运行队列长度(持续>CPU核数=CPU瓶颈)
# b: 阻塞队列(>0 且持续=IO/内存瓶颈)
# si/so: 换入换出(>0=内存不足,正在swap)
# us/sy/id/wa: 用户态/内核态/空闲/IO等待(wa高=IO瓶颈)

输出示例分析

text 复制代码
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  8      0  23456  12345 567890    0    0     0     0   10   20  5  3  0 92  0

🔴 危险信号b=8(大量阻塞),wa=92(CPU 几乎全在等待 IO),这就是"CPU 10% 但系统卡死"的典型场景。


IO 深度诊断

bash 复制代码
# 2. 磁盘 IO 实时监控(比 iostat 更直观)
iostat -xz 1

# 关键指标:
# %util: 接近 100% 表示磁盘饱和
# await: 平均等待时间(>20ms 需警惕,>50ms 严重)
# svctm: 服务时间(应接近物理极限,SSD<1ms,HDD<10ms)

比如这个情况:数据库备份导致业务卡顿

bash 复制代码
# 发现 nvme0n1 的 %util=99%,await=300ms
# 但 CPU 只有 15%
# 根因:备份进程占满磁盘带宽,业务 IO 排队

进阶工具

bash 复制代码
# 查看具体进程的 IO 情况
iotop -oP

# 查看 IO 延迟直方图(需 bcc 工具)
biolatency-bpfcc

内存与 Swap 陷阱

bash 复制代码
# 3. 内存深度分析
free -h && cat /proc/meminfo | grep -E "(Dirty|Writeback|AnonPages)"

# 关键观察点:
# - Dirty 数据大:大量数据待写盘,可能引发 IO 风暴
# - Writeback 高:正在回写,磁盘压力大
# - AnonPages 突增:应用内存泄漏或突发负载

隐形杀手:Swap 抖动

bash 复制代码
# 查看哪些进程在 swap
for pid in $(ls /proc | grep -E "^[0-9]+$"); do
    if [ -f /proc/$pid/smaps ]; then
        swap=$(awk '/Swap:/ {sum+=$2} END {print sum}' /proc/$pid/smaps 2>/dev/null)
        if [ "$swap" -gt 0 ]; then
            cmd=$(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ')
            echo "PID: $pid, Swap: ${swap}KB, CMD: $cmd"
        fi
    fi
done | sort -k3 -rn | head -10

网络与系统调用

bash 复制代码
# 4. 网络连接状态(连接数过多导致"假死")
ss -s
ss -tan state time-wait | wc -l  # TIME_WAIT 过多?
ss -tan state close-wait | wc -l # CLOSE_WAIT 泄漏?

# 5. 系统调用追踪(定位具体卡点)
strace -cp <pid>  # 统计耗时系统调用
strace -tt -T -p <pid> 2>&1 | head -100  # 查看具体延迟

生产环境排查实战

快速区分真假卡顿

排查的核心原则:先看整体指标,再抓具体进程,最后定位根因

核心命令组合:10 秒判断卡顿类型

执行以下命令组合,快速获取关键指标,判断卡顿类型:

bash 复制代码
# 1. 查看 CPU 使用率、进程状态、负载(核心指标)
top -c -n 1 -b | head -20

# 2. 查看系统负载(判断是否真过载)
uptime

# 3. 查看进程状态(区分 Running 与 Waiting)
ps -eo pid,cmd,%cpu,%mem,state --sort=-%cpu | head -10

# 4. 查看 IO 等待(关键:判断是否为 IO 导致的假卡顿)
iostat -x 1 3
指标解读
  1. load average :取 1 分钟平均值,若超过 CPU 核心数 × 2,大概率为真卡顿;
  2. %wa :若 wa > 20%,优先排查 IO 问题,而非 CPU;
  3. 进程 stateR(Running)为正在占用 CPU,D(不可中断睡眠)为等待 IO,S(可中断睡眠)为正常等待;
  4. CPU 使用率分布:us/sy 占比>90% 且 wa <5% → 计算密集型真卡顿;us/sy 占比<50% 且 wa >30% → IO 等待型假卡顿。
实战案例:识别假卡顿

生产场景 :监控报警业务服务器 CPU 使用率 92%,登录后执行 top 发现:

  • us 90%、sy 2%、wa 1%;
  • load average 1.5(CPU 核心数 4);
  • 前 3 个进程为业务日志压缩进程,state 均为 R,无请求队列积压;
  • 业务接口响应时间<100ms,正常无延迟。

结论 :此为计算密集型假卡顿,CPU 被日志压缩进程占用,但业务无影响,无需处理,仅需调整日志压缩策略即可。

CPU 飙高的 4 大核心场景与解决方案

若判断为真卡顿,按"进程 → 系统 → 代码"的顺序逐层排查,以下为生产环境最高频的 4 大场景,附实操命令与最佳实践。

业务进程 CPU 飙高

排查步骤

  1. 定位占 CPU 最高的进程 PID:

    bash 复制代码
    # 按 CPU 使用率排序,取前 5 个进程
    ps -p $(ps -eo pid --sort=-%cpu | head -n 6 | tail -n 5) -o pid,cmd,%cpu,%mem
  2. 定位进程内的高 CPU 线程:

    bash 复制代码
    # 替换 PID 为目标进程 ID,查看线程 CPU 占用
    top -H -p PID
  3. 分析线程堆栈(定位代码问题):

    bash 复制代码
    # 打印线程堆栈,保存到文件便于分析
    pstack PID > pid-stack.log
    # 或使用 perf 深度分析(生产环境谨慎使用,避免影响性能)
    perf trace -p PID -g > perf-trace.log
系统态 CPU 飙高(内核/调度问题)

排查步骤

  1. 查看系统态 CPU 占比:

    bash 复制代码
    mpstat 1 5
  2. 查看进程切换次数(上下文切换):

    bash 复制代码
    # 查看自愿/非自愿切换次数
    vmstat 1 5
    # 关键指标:cs(上下文切换次数),若>100万/秒,需排查
  3. 查看内核中断情况:

    bash 复制代码
    cat /proc/interrupts
常见原因与解决方案
原因 典型现象 解决方案
进程切换过多 sy >30%,cs >100万/秒 减少进程数、合并小进程、调整内核调度参数(如 sched_mc)
网络中断风暴 si >20%,网卡流量异常 排查 DDoS 攻击、优化网卡队列、开启网卡多队列(RSS)
磁盘中断异常 磁盘 IO 正常,sy 飙高 修复磁盘驱动、升级内核版本、调整 IO 调度算法(如 noop)
软中断 CPU 飙高(网络/磁盘问题)

排查步骤

  1. 查看软中断 CPU 占比:

    bash 复制代码
    watch -n 1 cat /proc/softirqs
  2. 定位高软中断类型:

    • NET_RX(网络接收)占比高 → 网络包风暴;
    • BLOCK(磁盘)占比高 → 磁盘 IO 异常;
  3. 排查网络/磁盘:

    bash 复制代码
    # 网络流量排查
    iftop -i eth0
    # 磁盘 IO 排查
    iotop -o
解决方案
  • 网络风暴:封禁异常 IP、接入 WAF、优化防火墙规则;
  • 磁盘异常:修复磁盘坏道、更换故障磁盘、清理无效文件、优化 IO 并发。
虚拟化层 CPU 限制(云服务器专属)

若为云服务器(如阿里云、腾讯云),可能是虚拟化层 CPU 限制导致的"假飙高":

  1. 查看 CPU 抢占情况:

    bash 复制代码
    cat /proc/schedstat
  2. 查看云厂商监控(如阿里云云监控):

    • 若出现 CPU 抢占时间(steal)>5% → 虚拟化层资源竞争,需提交工单扩容或更换宿主机。

构建你的卡顿排查 SOP

bash 复制代码
#!/bin/bash
# 快速卡顿排查脚本 - quick_check.sh

echo "=== 1. 系统负载与 CPU ==="
uptime
mpstat -P ALL 1 1 | tail -n 5

echo -e "\n=== 2. 内存与 Swap ==="
free -h
vmstat -s | grep -E "(swap|paged|pageout)"

echo -e "\n=== 3. IO 状态 ==="
iostat -xz 1 1 | tail -n 10

echo -e "\n=== 4. D 状态进程(卡顿元凶)==="
ps aux | awk '$8 ~ /^D/ {print $0}' | head -5

echo -e "\n=== 5. 网络连接 ==="
ss -s | head -10

echo -e "\n=== 6. 最近 OOM 或硬件错误 ==="
dmesg | grep -iE "(error|fail|oom|blocked)" | tail -5

总结:卡顿排查的思维模型

单个应用慢
整个系统无响应


❌ 无法登录
✅ 可以登录
CPU 高
内存不足
IO 瓶颈
网络问题
配置问题
代码问题
资源不足
外部攻击
🚨 用户反馈系统卡顿
卡顿范围判断
局部卡顿
全局卡顿
检查应用日志
应用本身问题?
修复应用配置/代码
SSH 能登录?
网络/内存严重问题
使用带外管理: IPMI/iLO/iDRAC
强制重启/现场排查
执行快速排查脚本
vmstat 1 5 - 查看 CPU/内存/IO
iostat -x 1 5 - 查看磁盘 IO
ss -s - 查看网络连接
dmesg | tail - 查看内核错误
定位资源瓶颈
top/htop 找高 CPU 进程
free -h / ps aux 找内存大户
iotop 找高 IO 进程
ss -tan 查看连接状态
使用 strace/pstack 分析进程
根因定位
调整系统/应用参数
修复代码/升级版本
扩容 CPU/内存/磁盘
封禁 IP/加固安全
✅ 问题修复
持续监控验证
记录复盘文档

最后的话 :优秀的运维不是"看到告警就处理",而是建立系统性的观测能力。当你能解释"为什么 CPU 20% 但系统卡死"时,你就真正理解了 Linux 的资源调度机制。


本文基于 Linux 内核 4.x/5.x 行为编写,工具以 CentOS/Ubuntu 通用版本为例。建议收藏并在测试环境验证命令后再用于生产。

相关推荐
gfdhy2 小时前
【Linux服务器】基础服务实战部署|Nginx+MySQL+PHP+WordPress,让服务器真正可用
linux·服务器·mysql·nginx·php·毕设
无人机9012 小时前
Delphi网络编程:项目优化与性能调优实战
运维
xingyuzhisuan2 小时前
给4090服务器配电源:8卡并行需要多少瓦才稳定?
服务器·网络·云计算·gpu算力
M158227690552 小时前
三格电子串口服务器:串口设备快速联网解决方案
运维·服务器
风酥糖2 小时前
Android上部署Linux环境的方案总结对比
android·linux·运维
A-刘晨阳2 小时前
K8s之StatefulSet控制器
运维·云原生·容器·kubernetes·statefulset
chase。2 小时前
Ubuntu 22.04 解决 nvblox 编译依赖冲突:libgoogle-glog-dev 安装问题全记录
linux·运维·ubuntu
有毒的教程10 小时前
Ubuntu 虚拟机磁盘空间不足完整解决教程
linux·运维·ubuntu
WiChP11 小时前
【V0.1B5】从零开始的2D游戏引擎开发之路
java·服务器·数据库