高负载排查:定位 CPU / 内存 / IO 瓶颈

服务器变慢或告警时,按"先看哪类资源满"的顺序,用 top、free、iostat、ss 一步步定位瓶颈。

当你的服务器或 VPS 变慢、响应超时、监控告警时,不要盲目重启。系统资源无非 CPU、内存、磁盘 IO、网络四类,只要按顺序逐一排除,就能快速找到真正吃满的那一类。下面是一套实用的排查流程。

第一步:读懂 load average

先用 uptime 或 top 看系统负载:

uptime
# 15:04:01 up 30 days,  load average: 3.20, 2.80, 1.90

三个数字分别是过去 1、5、15 分钟的平均负载。关键是把它和 CPU 核数 对比:

nproc          # 查看逻辑核数,比如返回 4

经验法则:load 约等于核数时,系统满载但仍健康;load 持续高于核数(如 4 核 load 长期 8+)说明有任务在排队等待。注意 load 统计的不只是 CPU,还包括处于不可中断状态(D 状态,通常在等 IO)的进程——所以高 load 不一定是 CPU 问题,得继续往下看。

第二步:CPU 是不是瓶颈

用 top(或更直观的 htop)按 CPU 排序找元凶:

top          # 按大写 P 按 CPU 排序,按 1 展开每个核
htop         # 若已安装,界面更友好,F6 可选排序字段

重点看 top 顶部这行:

  • us(用户态)高 → 应用自身在算,定位到具体进程。
  • sy(内核态)高 → 系统调用/上下文切换频繁。
  • wa(iowait)高 → CPU 在等磁盘,别怀疑 CPU,转去查 IO。
  • st(steal)高 → 宿主机把 CPU 时间片分给了别的虚拟机,是共享型 VPS 的典型现象。

第三步:内存与 swap

用 free -h 看内存全貌:

free -h
#               total   used   free   shared  buff/cache  available
# Mem:           7.7Gi  5.1Gi  0.3Gi   0.2Gi       2.3Gi       2.2Gi

看 available 而不是 free——buff/cache 可被随时回收。若 available 很低、Swap 的 used 持续增长,说明内存吃紧、系统在换页,会拖慢一切。用 vmstat 观察动态:

vmstat 1 5     # 每秒采样,共 5 次

关注 si/so(换入/换出)列,持续非 0 就是在频繁 swap。若进程被系统杀掉,查 OOM 日志:

dmesg -T | grep -i -E 'killed process|out of memory'
journalctl -k | grep -i oom

看到 Out of memory: Killed process 就说明触发了 OOM Killer,该扩内存或排查内存泄漏。

第四步:磁盘 IO 等待

当 top 的 wa 偏高,用 iostat 定位磁盘:

iostat -x 1 3    # 需 sysstat 包:apt install sysstat

重点看 %util(接近 100% 说明磁盘忙满)和 await(平均 IO 耗时,偏高说明慢)。再用 iotop 找出具体是哪个进程在读写:

sudo iotop -o    # -o 只显示有实际 IO 的进程

第五步:连接数与网络

若怀疑是连接堆积,用 ss 统计:

ss -s                          # 连接总览
ss -tan | awk '{print $1}' | sort | uniq -c   # 按状态计数
ss -tanp | grep :80            # 看某端口的连接与进程

大量 TIME-WAIT 通常正常;大量 CLOSE-WAIT 往往是应用没正确关连接。

小结

排查顺序记牢:load 对比核数 → top 看 CPU(us/sy/wa/st)→ free/vmstat 看内存与 swap → iostat/iotop 看磁盘 → ss 看连接。核心是先判断"哪类资源满",再顺着往下钻到具体进程。高 load 未必是 CPU,wa 高要转查 IO,内存耗尽会 OOM 杀进程——定位准了,才知道该扩容、调参还是改代码。