Linux 服务器 CPU / 内存 / IO 如何排查瓶颈

Linux 服务器 CPU / 内存 / IO 如何排查瓶颈

服务器突然变慢、响应卡顿、甚至出现超时告警,这些场景几乎每个做过线上服务的同学都遇到过。很多时候,根源就藏在 CPU内存磁盘IO 这三大资源瓶颈里。今天这篇文章就来系统聊聊:在Linux服务器上,如何一步步排查这三个维度的性能瓶颈,哪些指标最关键,用什么工具最有效,以及常见的误区和优化思路。

一、排查前的整体思路:USE 方法 + 分层诊断

在正式动手之前,先说一个排查心法:USE 方法(Utilization 利用率、Saturation 饱和度、Errors 错误数),这是Brendan Gregg 大神提出的黄金诊断框架。简单来说:

  • Utilization:资源被用了多少?(太高 → 可能瓶颈)
  • Saturation:资源队列有多长?(队列积压 → 肯定有瓶颈)
  • Errors:有没有出错?(错误频发 → 硬件或配置问题)

排查顺序推荐:先整体概览 → 再逐资源深挖 → 最后定位到具体进程/代码

常用“一分钟概览”命令组合(强烈建议做成alias或脚本):

Bash
uptime                  # load average 快速看整体压力
top                     # 或 htop,看 CPU/内存/进程
free -h                 # 内存使用
vmstat 1 5              # CPU、内存换页、IO 概览
iostat -xdz 1 5         # 磁盘IO 详细(-x 扩展统计、-d 只看磁盘、-z 忽略0活动设备)
sar -u 1 5              # CPU(需 sysstat 包)

如果 load average 远高于 CPU 核数,且 wa(iowait)很高,先怀疑 IO;如果 us+sy 很高且 id 很低,先看 CPU;如果 swap 使用量飙升或 si/so 不为0,先查内存。

下面按 CPU → 内存 → IO 的顺序详细拆解。

二、CPU 瓶颈排查

2.1 关键指标判断 CPU 是否是瓶颈

  • us(user) + sy(system) 持续 > 80-90%,id(idle) 接近0 → CPU 饱和
  • wa(iowait) 持续 > 20-30% → 不是 CPU 忙,而是等 IO(本质是 IO 瓶颈)
  • load average 远高于核数(例如 16 核机器 load 常年 40+)且 CPU 使用率不高 → 大量进程在等待(通常是 IO 或锁)
  • 单核跑满(mpstat 看到某核 100%,其他低) → 单线程瓶颈或中断不均衡

2.2 常用工具及用法

  1. top / htop(最常用入门工具)

    Bash
    top -c          # 显示完整命令行,按 1 查看每核使用率
    htop            # F5 树形查看进程树,F6 按 CPU 排序

    看 %CPU 列,找到占用最高的进程。

  2. mpstat(每核详细)

    Bash
    mpstat -P ALL 1 5       # 每秒刷新5次,看哪颗核饱和
  3. pidstat(进程级 CPU)

    Bash
    pidstat -w -u 1         # -u CPU,-w 上下文切换
  4. perf(火焰图级深度分析,推荐生产神器)

    Bash
    perf top                # 实时看占用 CPU 的函数
    perf record -p <PID> -g -- sleep 10
    perf report             # 生成调用栈

    常用于定位 Java/Python/Node 等热点函数、锁竞争、系统调用过多等。

2.3 常见 CPU 瓶颈场景及处理

  • 用户态 us 过高 → 业务代码死循环、复杂计算、正则、加密解密 → 用 perf 找热点函数优化
  • 系统态 sy 过高 → 频繁系统调用(select/poll/epoll 问题、大量小文件读写) → 优化 IO 模型或批量处理
  • 上下文切换 cs 极高(> 10000/s) → 线程过多 → 减线程、用协程
  • iowait wa 高 → 别优化 CPU,先看下面 IO 章节

三、内存瓶颈排查

3.1 关键指标判断内存是否瓶颈

  • free -h 中 available < 10% 物理内存,且 swap 已使用 → 内存压力大
  • vmstat 的 si/so(swap in/out)不为 0 且持续 → 严重内存不足,正在疯狂换页
  • sar -r %memused 持续接近 100%,且 %commit 超 100% → overcommit 风险
  • slabtop 看到 dentry/inode 等缓存占用极高 → 文件系统元数据压力

3.2 常用工具及用法

  1. free -h(快速看)

    重点关注 available(真正可用的内存),而不是 free 列(被缓存占用了也算可用)。

  2. vmstat 1 5

    关注 free(剩余物理内存)、si/so(换页速率)、swpd(swap 使用量)

  3. top / htop → 看 RES(驻留内存)、VIRT(虚拟内存)、SHR(共享)

  4. smemps 查看进程真实内存占用(比 top 更准)

    Bash
    ps -eo pid,ppid,rss,vsz,cmd --sort=-rss | head -20   # 按 RSS 降序
  5. /proc/meminfo + slabtop

    检查 Slab、SReclaimable 是否过大(文件缓存)。

3.3 常见内存瓶颈场景及处理

  • 内存泄漏 → Java 进程 OldGC 频繁、Python 进程驻留暴涨 → 用 heap dump / malloc 分析
  • 缓存占用过多 → Linux 会尽量把空闲内存当 page cache 用,无需慌张;但如果 dirty pages 过多会导致写阻塞
  • OOM Killer 被触发 → dmesg | grep -i ‘out of memory’ 查看谁被杀
  • Swap 使用过多 → 调低 swappiness(echo 10 > /proc/sys/vm/swappiness),或加内存/优化程序

四、IO 瓶颈排查(磁盘 IO 最容易被忽略)

4.1 关键指标判断 IO 是否瓶颈

  • iostat -x %util 持续 > 80-90% → 磁盘饱和
  • await(平均等待时间) > 10-20ms(SSD)或 > 50ms(HDD) → 延迟高
  • top wa(iowait) > 30% → 系统在等磁盘
  • r/s + w/s(IOPS)接近磁盘极限 → 随机读写过多
  • svctm(服务时间)高 → 队列饱和

4.2 常用工具及用法

  1. iostat -xdz 1 5(最核心)

    • %util:磁盘利用率(最重要)
    • await:平均 IO 等待时间
    • svctm:平均服务时间
    • r/s w/s:读写次数
    • rkB/s wkB/s:吞吐量
  2. iotop(进程级 IO 神器,像 top 一样看谁在狂写磁盘)

    Bash
    iotop -o         # 只显示有 IO 的进程
  3. vmstat 的 bi/bo(块读/写)

  4. sar -d 历史 IO

  5. blktrace / btt(深度分析,生产慎用,会产生大量日志)

4.3 常见 IO 瓶颈场景及处理

  • MySQL/Redis 大量随机写 → %util 高,await 高 → 加索引、优化查询、用 SSD、分库分表
  • 日志狂写 → 日志级别调到 warn、异步写日志、日志切割
  • 大量小文件读写 → 元数据压力大 → 用 xfs/ext4 优化、增大 inode 缓存
  • 脏页回写阻塞 → vm.dirty_ratio / dirty_background_ratio 调小
  • 多盘 RAID0/10 还是单盘 → 升级 NVMe SSD 或分布式存储

五、快速 checklist + 实战脚本建议

把下面几行做成脚本 check-bottleneck.sh,一键跑:

Bash
#!/bin/bash
echo "=== Load & CPU ==="; uptime; mpstat 1 3 | tail -n +4
echo "=== Memory ==="; free -h; vmstat 1 3 | tail -n +3
echo "=== Disk IO ==="; iostat -xdz 1 3
echo "=== Top processes ==="; top -b -n1 -o %CPU | head -20
echo "=== IO processes ==="; iotop -b -n1 -o | head -15

结语

排查瓶颈的核心是“先定性、再定位、最后优化”。别一上来就调参数,先用 top/vmstat/iostat 确认到底是 CPU/内存/IO 中的哪一个(或多个)在作妖,再用 perf/iotop/strace 深挖具体进程和代码。

大多数线上问题,80% 都能通过上面这些免费工具在 10-30 分钟内定位到大概原因。剩下的 20% 才需要火焰图、eBPF、systemtap 等高级手段。

Telegram
Telegram@IDCSELL