load 飙到 21 但 CPU 几乎空闲:一次 Linux swap 颠簸拖垮服务器的复盘

一台 4 核 8G 的应用服务器,服务慢到接口大量超时,SSH 登录卡、敲命令字一个个蹦。top 一看 load average 高达 21,可 CPU 的 us+sy 才 8%,iowait 却高达 63%——负载爆表,CPU 却闲着。free 显示物理内存 7.1G/7.6G 榨干、swap 2G 也用满,vmstat 的 si/so 两列持续几千在疯狂换页。排查梳理:load average 不是 CPU 使用率,它统计在用 CPU 加上卡在不可中断 IO 等待里的进程数,所以会出现 load 高 CPU 闲;load 高先看 top 的 CPU 行,us/sy 高是算力瓶颈,iowait 高是 IO 瓶颈;swap 是磁盘上的备用内存,内存吃紧时系统把暂时不用的页挪过去应急,但它比内存慢上万倍,是安全垫不是内存扩容;swap 颠簸是内存缺口太大导致页反复换进换出的恶性循环,机器活着但比死还卡;vmstat 的 si so 两列持续非 0 是颠簸的确诊指标;颠簸根治只有加物理内存或减少内存占用两条路,降 -Xmx 修泄漏拆服务都属于减占用;swappiness 控制系统多爱用 swap,调低能缓解轻度换页但救不了真实的内存不足;监控要盯物理内存余量和 swap 使用率和 si/so 在颠簸形成前告警。正确做法是先重启内存大户止血再加内存或降占用根治,以及一套内存与 swap 排查纪律。

2023 年,一台服务器把我对"忙"这个字的理解彻底搞乱了。那天下午,告警先响了:这台机器上的服务,响应慢到几乎不可用,接口动不动就超时。我赶紧 SSH 上去——光是登录,就卡了好久,连我敲的命令,字都是一个一个往外蹦的。我心想,这肯定是 CPU 被打满了,某个进程在疯狂吃 CPU。我 top 一看,第一个数字就把我看懵了:load average21.8。21!这台机器才 4 核,负载 21,按我以往的经验,这是 CPU 被往死里压的节奏。可我把目光往 top 的 CPU 那一行挪——%us 用户态占用,只有 3%;%sy 系统态,5%;真正吓人的不是它们,是 %id(空闲)居然还有不少,而 %wa(iowait)那个数字,高得刺眼。我彻底糊涂了:负载明明高到 21,可 CPU 根本没在拼命算,它甚至有一部分时间是【空闲】的。一台机器,负载爆表,可它的 CPU 居然是闲的——这怎么可能?如果不是 CPU 在忙,那这 21 的负载,到底是谁、在哪里、堆出来的?这件事逼着我把 load average 的真正含义、swap、内存换页、vmstatsi/so 这一整套彻底理清了。本文复盘这次实战。

问题背景

环境:CentOS 7,4 核 8G 内存的应用服务器
事故现象:
- 服务响应极慢,接口大量超时
- SSH 登录卡、敲命令字一个个蹦
- ★ load average 高达 21,但 CPU 大部分不忙

现场排查:
# 1. top 看负载和 CPU
$ top
top - 15:20:01 up 90 days, load average: 21.8, 20.3, 18.1
%Cpu(s):  3.0 us,  5.0 sy,  0.0 ni, 28.0 id, 63.0 wa, ...
#                                       ^^^^   ^^^^
#                                       空闲   ★ iowait 高达 63%!
# ★ load 21,但 us+sy 才 8% —— CPU 没在拼命算。
#   63% 的时间,CPU 在【等 IO】。

# 2. ★ free 看内存 —— 关键线索
$ free -h
              total   used   free   shared  buff/cache  available
Mem:           7.6G   7.1G   102M     12M       420M       180M
Swap:          2.0G   2.0G     0B
#              ^^^^   ^^^^   ^^^^
# ★ 物理内存 7.6G,用了 7.1G,几乎榨干。
# ★ Swap 2G,也【用满了】—— available 只剩 180M。

# 3. ★ vmstat 看换页 —— 一锤定音
$ vmstat 2
procs -----------memory----------  ---swap--  -----io----
 r  b   swpd   free   buff  cache   si   so    bi    bo
 8 12 2097148  98000  10000 400000 4800 5200 12000 14000
 9 15 2097148  95000  10000 398000 5100 4900 13000 13500
#                                  ^^^^ ^^^^
# ★ si(swap in)、so(swap out)持续几千 ——
#   内存页在【疯狂地换进换出】磁盘。
# ★ b 列(不可中断阻塞)十几个进程,全卡在 IO 上。

# 4. 看是谁在吃内存
$ ps aux --sort=-%mem | head -5
USER  PID  %MEM  RSS      COMMAND
app   2345 71.0  5500000  java -Xmx6g ...     # ★ 一个 java 吃了 5.5G
...

根因(后来想清楚的):
1. ★ load average 不只统计"在用 CPU 的进程",还统计
   "卡在不可中断 IO 等待里的进程"。CPU 不忙,
   但一堆进程卡在磁盘 IO 上 —— load 照样飙高。
2. ★ 物理内存被榨干了(7.1G/7.6G),系统只能动用
   swap —— 把一部分内存页"挪"到磁盘上。
3. ★ 但内存缺口太大,swap 也用满了。系统陷入
   【swap 颠簸】:刚换出去的页,马上又要用,
   又得换回来;换回来又挤掉别的页…… 循环往复。
4. ★ 磁盘比内存慢几个数量级。进程要用的内存页
   在磁盘上,它就得【停下来等磁盘】—— 这就是
   那 63% 的 iowait,和那十几个卡在 b 列的进程。
5. 于是:CPU 没怎么干活(没东西可算),可所有
   进程都在排队等磁盘把内存页搬回来 —— 负载 21,
   全是"等出来的",不是"算出来的"。
不是 CPU 被打满了,是内存不够、系统在拿磁盘当内存用,
整台机器卡在了换页的泥潭里。

修复 1:load average 到底统计了什么

# === ★ 先纠正一个根深蒂固的误解:load ≠ CPU 使用率 ===

# === ★ 误解:"load 高 = CPU 被打满" ===
# 这是我多年的想当然。但它【不准确】。
# ★ load average 统计的,是"系统里处于以下两种状态
#   的进程数量"的平均值:
#   1) 正在【使用 CPU】(running);
#   2) ★【在等不可中断资源】(uninterruptible,
#      最典型就是等磁盘 IO)—— 也就是 D 状态。
# ★ 关键:第 2 种,根本没在用 CPU!它在【等】。

# === ★ 所以会出现"load 高、CPU 闲"的局面 ===
# 如果有 20 个进程,全都卡在"等磁盘"上:
#  - 它们一个都没在用 CPU -> CPU 可以是空闲的;
#  - 但它们都是"在运行队列/等待里"的进程
#    -> ★ load average 照样 ≈ 20。
# 这正是本文的现场:load 21,CPU 却不忙。

# === ★ 怎么区分 load 高是"算"还是"等" ===
$ top
%Cpu(s): 3.0 us, 5.0 sy, 28.0 id, 63.0 wa
# ★ 看 CPU 那一行的两个关键值:
#  - us + sy 高     -> CPU 真在拼命算(算力瓶颈)
#  - ★ wa(iowait)高 -> CPU 在【等 IO】(IO 瓶颈)
# 本文 wa=63%,一眼定性:这是 IO 问题,不是算力问题。

# === ★ vmstat 的 r 列和 b 列,把这事说得更清楚 ===
$ vmstat 2
 r  b   swpd  free ...
 8 12 2097148 ...
# ★ r 列:正在运行 / 等 CPU 的进程数。
# ★ b 列:★【处于不可中断阻塞】(等 IO)的进程数。
# 本文 b=12 —— 十几个进程卡在 IO 上动弹不得。
#   load 的大头,就是这个 b 撑起来的。

# === ★ load 高的两种完全不同的病 ===
# 病 A:r 列大、us/sy 高 -> CPU 不够用(真·算力瓶颈)
#        药方:优化代码 / 加 CPU / 减并发
# 病 B:★ b 列大、wa 高   -> 进程全卡在 IO 等待
#        药方:找 IO 为什么慢(本文:内存不够在换页)
# ★ 同样是 load 21,两种病,药方截然相反。先分清。

# === 认知 ===
# ★ load average 不是 CPU 使用率。它算的是"在用
#   CPU 的"加上"卡在不可中断 IO 等待里的"进程数。
#   load 高、CPU 却闲,说明负载的来源不是计算,
#   而是【等待】—— 接下来要查的是:在等什么。

修复 2:swap 是什么——拿磁盘当"备用内存"

# === ★ 理解 swap:内存不够时的"应急仓库" ===

# === ★ swap 是什么 ===
# 物理内存(RAM)是有限的。当内存快用光时,Linux
#   有一个应急机制:★ 把一部分【暂时不太用】的
#   内存页,"挪"到磁盘上的一块专门区域里存着,
#   把腾出来的物理内存,给更急需的进程用。
# ★ 这块磁盘上的"内存暂存区",就叫 swap(交换空间)。
#   它让系统"看起来"有比物理内存更多的内存可用。

# === ★ swap 长什么样 ===
$ swapon --show
NAME      TYPE  SIZE   USED  PRIO
/dev/vdb2 partition 2G  2.0G   -2
# ★ swap 可以是一个独立分区,也可以是一个文件。
$ free -h
              total  used  free  ...
Mem:           7.6G  7.1G  102M
Swap:          2.0G  2.0G   0B               # ★ swap 也满了
# ★ free 的 Swap 行,直接告诉你 swap 有多大、用了多少。

# === ★ 换出 / 换入:页在内存和 swap 之间搬家 ===
# - ★ swap out(换出):内存页 -> 写到磁盘 swap。
# - ★ swap in (换入):swap 里的页 -> 读回内存。
# 进程要访问一个"已经被换出到磁盘"的内存页时,
#   系统必须先把它【换入】回内存,进程才能继续。
# ★ 而这个"换入",是一次【磁盘读】—— 慢。

# === ★ 关键:swap 在磁盘上,比内存慢几个数量级 ===
# 内存的访问速度,以纳秒计;
# 磁盘(哪怕 SSD)的访问,以微秒甚至毫秒计。
# ★ 差距是【成千上万倍】。一个进程,本该从内存里
#   瞬间拿到的数据,如果那页被换到了 swap,它就得
#   等一次磁盘 IO —— 慢到天上去。

# === ★ swap 的正确定位:是"保命的",不是"扩容的" ===
# swap 的本意,是在内存突然吃紧时,给系统一个
#   【缓冲】,别让进程直接被 OOM 杀掉 —— 它是
#   "应急安全垫"。
# ★ 它【不是】用来"让 8G 内存的机器当 16G 用"的。
#   一旦你真的长期靠 swap 来弥补内存缺口,性能
#   就会掉进深渊 —— 这就是下一节的"颠簸"。

# === 认知 ===
# ★ swap 是磁盘上的一块"备用内存",内存吃紧时系统
#   把暂时不用的页挪过去应急。但它在磁盘上,慢得
#   要命。它是"保命的安全垫",绝不是"免费的内存
#   扩容"。偶尔用一点没事,长期重度依赖就是灾难。

修复 3:swap 颠簸——整台机器陷进的泥潭

# === ★ swap thrashing(颠簸):本文真正的病名 ===

# === ★ 偶尔用 swap,和"颠簸",是两回事 ===
# 内存稍紧,把几个真的"很久不碰"的页换出去 ——
#   这没问题,系统设计就该这样,你甚至感觉不到。
# ★ 但"颠簸(thrashing)"是另一回事:
#   当内存缺口【太大】,系统被迫换出去的,已经
#   不是"不用的页",而是"马上还要用的页"。

# === ★ 颠簸是怎么形成的恶性循环 ===
# 1. 内存满了,系统换出页 A 给进程腾地方。
# 2. ★ 可是进程下一秒就要用页 A —— 只好把 A 换回来。
# 3. 换 A 回来,又没地方,只好换出页 B。
# 4. ★ 紧接着又要用 B …… 换 B 回来,再换出 C ……
# ★ 系统把绝大部分精力,都耗在了"搬页子"上,
#   反而没空真正去执行进程。这就是颠簸 —— 像一个
#   小桌子上摊了太多文件,你每拿一份都得先收起
#   另一份,最后一整天都在收收放放,什么活没干。

# === ★ 颠簸时,机器的典型症状(就是本文现场)===
# - load average 飙高(一堆进程卡在等换页 IO)
# - ★ 但 CPU 的 us/sy 很低,iowait(wa)极高
# - vmstat 的 si / so 持续是几千上万
# - 整机巨卡:连 SSH、敲命令都一顿一顿的
# - ★ 注意:此时进程还【没被 OOM 杀掉】,机器也
#   没宕 —— 它就是"活着,但卡死了",最难受的状态。

# === ★ 为什么颠簸比"直接 OOM"还让人头疼 ===
# 如果内存真的瞬间爆掉,OOM Killer 会杀掉一个进程,
#   干脆利落,机器至少还能用。
# ★ 但颠簸是"温水煮青蛙":机器没死,只是慢,慢到
#   你执行任何排查命令都要等半天,慢到你想杀进程
#   都半天敲不出命令。它把机器拖进一种"半死不活"
#   的拉锯里 —— 这才是它最磨人的地方。

# === ★ 一眼确认是不是颠簸 ===
$ vmstat 2 5
# ★ 连看几秒:si 和 so 两列,如果【持续】都是
#   几百几千、不归零 —— 基本就是在颠簸了。
# ★ 健康的机器,si/so 长期应该是 0 或个位数。

# === 认知 ===
# ★ swap 颠簸,是内存缺口大到系统只能反复换进换出
#   "马上要用的页",把算力全耗在搬运上的恶性循环。
#   症状就是 load 高、CPU 闲、iowait 爆表、si/so
#   持续不停。机器没死,但比死还难受。

修复 4:vmstat——把换页看得清清楚楚

# === ★ vmstat:诊断内存/换页问题的核心工具 ===

# === ★ 怎么跑 vmstat ===
$ vmstat 2
# ★ "2" = 每 2 秒刷一行。第一行是开机以来的平均值,
#   【没参考价值】,要看的是第二行往后的【实时】数据。
$ vmstat 2 10        # 每 2 秒一行,共 10 行后停

# === ★ 一行 vmstat,逐列拆给你看 ===
$ vmstat 2
procs -----------memory----------  ---swap-- -----io---- --system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so   bi    bo    in   cs  us sy id wa
 8 12 2097148 98000 10000 400000  4800 5200 12000 14000 ...        3  5 28 63

# ★ procs:
#   r  -> 等 CPU / 在跑的进程数
#   b  -> ★ 不可中断阻塞(等 IO)的进程数
# ★ memory:
#   swpd  -> ★ 已用的 swap 大小(KB)。本文 2097148 ≈ 2G,满了
#   free  -> 空闲物理内存。本文 98000 ≈ 98M,几乎没了
#   buff/cache -> 缓存占的内存
# ★ swap:★★ 本节重点 ★★
#   si -> swap in :每秒从 swap 【换入】内存的量(KB)
#   so -> swap out:每秒从内存【换出】到 swap 的量(KB)
# ★ io:
#   bi/bo -> 块设备每秒读/写
# ★ cpu:
#   us/sy/id/wa -> 用户/系统/空闲/等IO 的百分比

# === ★ 看 vmstat,第一眼就盯住 si 和 so ===
# ★ 健康机器:si 和 so 长期是 0,或偶尔个位数。
# ★ 本文机器:si≈4800、so≈5200,持续不归零 ——
#   每秒有几 MB 的内存页在和磁盘之间来回搬。
#   这就是颠簸的【铁证】。

# === ★ si/so 持续非 0,配合这几列一起读 ===
# si/so 高 + free 极低 + swpd 满 + b 列大 + wa 高
# ★ —— 这一组数字同时出现,内存不足导致 swap 颠簸,
#   实锤,不用再猜。

# === ★ 对照:别把 si/so 和 bi/bo 搞混 ===
# bi/bo:所有块设备 IO(包括正常读写文件)。它高,
#   不一定是坏事 —— 可能就是在正常读写数据。
# ★ si/so:专指【换页】IO。它持续高,几乎总是坏事 ——
#   说明内存在被当磁盘用。盯 si/so,别只看 bi/bo。

# === ★ 还可以看每个进程的 swap 占用 ===
$ for f in /proc/*/status; do
    awk '/^Name|^VmSwap/{printf "%s ",$2} END{print ""}' $f
  done | sort -k2 -n | tail
# ★ 找出"哪个进程被换出去最多",辅助定位内存大户。

# === 认知 ===
# ★ vmstat 是看换页的眼睛。它的 si / so 两列,直接
#   告诉你内存页有没有在和磁盘疯狂对搬。si/so 持续
#   非 0,就是 swap 颠簸的确诊指标 —— 比 top 的 load
#   更能说明"问题到底出在内存"。

修复 5:正确解法——把机器从换页泥潭里捞出来

# === ★ 解法:先止血恢复,再根治内存缺口 ===

# === ★ 解法 1:止血——找出内存大户,该杀杀该重启重启 ===
$ ps aux --sort=-%mem | head -5
USER  PID  %MEM  RSS       COMMAND
app   2345 71.0  5500000   java -Xmx6g ...
# ★ 一个 -Xmx6g 的 java,在 8G 的机器上,本身就
#   注定要把内存逼到极限。先把它(或别的失控进程)
#   重启 / 降配,让物理内存先松一口气。
$ systemctl restart myapp     # 重启它,内存立刻回落
# ★ 颠簸时机器极卡,敲命令都难 —— 耐心等,别狂敲。

# === ★ 解法 2:根治——内存缺口要么加内存,要么减占用 ===
# 颠簸的【唯一根因】是:要用的内存 > 物理内存。
# 真正的根治,只有两条路:
#  A. ★ 加物理内存(最直接,加到够用)。
#  B. ★ 减少内存占用:
#     - JVM 应用:把 -Xmx 调到"物理内存留足余量"
#       (别让 -Xmx 逼近物理内存总量);
#     - 排查内存泄漏;
#     - 把挤在一台机器上的服务拆出去。
# ★ 不解决这个缺口,做别的都只是缓解。

# === ★ 解法 3:调 swappiness——控制系统"多爱用 swap" ===
$ cat /proc/sys/vm/swappiness
60                              # ★ 默认值,常见 30 或 60
# ★ swappiness(0~100):值越高,系统越"倾向于"
#   主动把内存页换到 swap;越低,越尽量留在物理内存。
# 临时改:
$ sysctl vm.swappiness=10
# 永久改:
$ echo 'vm.swappiness=10' >> /etc/sysctl.conf && sysctl -p
# ★ 注意:调低 swappiness 能让系统"晚一点动用 swap",
#   缓解轻度换页。但内存真不够时,它【救不了】你 ——
#   该颠簸还是颠簸。它是调优,不是根治。

# === ★ 解法 4:swap 该配多大——别配太小,也别指望它 ===
# - swap 配太小(甚至没有):内存一满,直接 OOM 杀进程。
# - swap 配太大:给了系统"长期靠 swap 硬撑"的空间,
#   反而让机器在颠簸里"求生不得求死不能"。
# ★ 经验:给一块【合理大小】的 swap 当安全垫(让系统
#   有缓冲、不至于秒 OOM),但真实负载必须由【物理
#   内存】扛住。靠 swap 扛业务 = 性能自杀。

# === ★ 解法 5:加监控,在颠簸前就告警 ===
# 别等服务超时了才发现。监控里盯住:
#  - 物理内存 available 余量
#  - ★ swap 使用率(swap 一开始被大量占用,就是预警)
#  - vmstat 的 si/so(持续非 0 立即告警)
$ free -h ; vmstat 2 3
# ★ 把"swap 用量上涨"变成一条早期告警 —— 在颠簸
#   形成、机器卡死之前就介入。

# === 验证 ===
$ free -h                       # ★ swap used 回落,available 恢复
$ vmstat 2 5                     # ★ si / so 回到 0
$ top                            # ★ load 下来、iowait 降下来
# ★ swap 用量降下来 + si/so 归零 + load 回落 ——
#   才算真把机器从泥潭里捞出来了。

口诀放进脑子:load 高 CPU 闲先看 free 和 vmstat,si/so 持续非 0 就是 swap 颠簸,根治靠加内存或降占用。

修复 6:内存与 swap 排查纪律

# === 这次事故暴露的认知盲区,定几条纪律 ===

# === 1. ★ load average 不是 CPU 使用率,它含"等不可中断 IO"的进程 ===

# === 2. ★ load 高先看 top 的 CPU 行:us/sy 高是算力瓶颈,wa 高是 IO 瓶颈 ===

# === 3. ★ load 高 CPU 却闲,第一时间 free -h 看内存和 swap ===
$ free -h

# === 4. ★ vmstat 2 看 si/so,持续非 0 就是 swap 颠簸 ===
$ vmstat 2

# === 5. swap 是磁盘上的备用内存,比内存慢上万倍,是安全垫不是内存扩容 ===

# === 6. ★ swap 颠簸是内存缺口太大、页反复换进换出的恶性循环,机器没死但比死还卡 ===

# === 7. ★ 颠簸根治只有两条路:加物理内存,或减少内存占用(降 -Xmx / 修泄漏 / 拆服务)===

# === 8. swappiness 控制系统多爱用 swap,可调优缓解,但救不了真实的内存不足 ===

# === 9. ★ 监控要盯物理内存余量 + swap 使用率 + si/so,在颠簸形成前告警 ===

# === 10. 排查"load 爆高但 CPU 不忙"的步骤链 ===
$ top                            # ① load 高?us/sy 低、wa 高?
$ free -h                        # ② 物理内存和 swap 是不是都满了
$ vmstat 2                       # ③ si/so 是不是持续非 0(颠簸确诊)
$ ps aux --sort=-%mem | head     # ④ 揪出内存大户
$ 重启大户止血 + 加内存/降占用根治  # ⑤ 治本
# 按这个顺序,"负载爆表却找不到忙的 CPU"基本能定位、能根治。

命令速查

需求                        命令
=============================================================
看负载和 CPU                top
看内存和 swap               free -h
看换页(si/so)实时         vmstat 2
看换页 + 进程阻塞数         vmstat 2(看 r/b/si/so 列)
看 swap 设备                swapon --show
按内存排序看进程            ps aux --sort=-%mem | head
看某进程被换出多少          cat /proc/PID/status | grep VmSwap
看 swappiness               cat /proc/sys/vm/swappiness
临时调 swappiness           sysctl vm.swappiness=10
永久调 swappiness           echo 'vm.swappiness=10' >> /etc/sysctl.conf

口诀:load 高 CPU 闲,先 free 看内存再 vmstat 看 si/so
      si/so 持续非 0 就是 swap 颠簸,根治只能加内存或减占用

避坑清单

  1. load average 不是 CPU 使用率,它统计的是在用 CPU 加上卡在不可中断 IO 等待里的进程数
  2. load 高先看 top 的 CPU 行,us/sy 高是算力瓶颈,iowait 高是 IO 瓶颈,两者药方相反
  3. load 高但 CPU 空闲说明负载来自等待不是计算,第一时间用 free -h 看内存和 swap
  4. swap 是磁盘上的一块备用内存,内存吃紧时系统把暂时不用的页挪过去应急
  5. swap 在磁盘上比内存慢成千上万倍,它是保命的安全垫不是免费的内存扩容
  6. swap 颠簸是内存缺口太大导致页反复换进换出的恶性循环,机器活着但卡到比死还难受
  7. vmstat 的 si 和 so 两列持续非 0 是 swap 颠簸的确诊指标,健康机器它们应长期为 0
  8. 颠簸根治只有加物理内存或减少内存占用两条路,降 -Xmx 修泄漏拆服务都属于减占用
  9. swappiness 控制系统多倾向用 swap,调低能缓解轻度换页但救不了真实的内存不足
  10. 监控要盯物理内存余量和 swap 使用率和 si/so,在颠簸形成机器卡死之前就告警介入

总结

这次"负载 21,CPU 却闲着"的事故,纠正了我一个埋在思维深处、却从没被我审视过的等式:负载高 = 在拼命干活。在我过去所有的排查经验里,这个等式是不证自明的。一个系统"压力大",在我脑子里,就等同于它"正在使尽全力地运转"——所以我看到 load 21 的第一反应,是冲去找那个"把 CPU 榨干的进程",我笃定一定有这么一个"忙到冒烟"的家伙存在。可现场把这个等式,当着我的面,撕得粉碎:负载高到 21,而 CPU,这台机器真正负责"干活"的器官,却有相当一部分时间是【空闲】的。它不忙。这个画面一度让我大脑短路——一台"压力爆表"的机器,它的"干活的手"却闲着,这两件事怎么可能同时成立?复盘到根上,我才看清那个被我忽略了太久的真相:load 这个数字,它统计的从来就不是"有多少进程在干活",而是"有多少进程,卡在那里、动弹不得"。而"动弹不得",有两种完全不同的成因:一种,是它【想干活,但 CPU 不够分,得排队等 CPU】——这是"忙";另一种,是它【根本干不了活,因为它要用的东西不在手边,它在傻等磁盘把东西搬回来】——这是"堵"。这台机器的 21,几乎全是第二种。它不是 21 个进程在拼命算,而是 21 个进程,一起被堵在了同一个地方,排着一条望不到头的队,每个人都在等前面那个慢吞吞的磁盘。负载,衡量的是"卡住的程度",不是"勤奋的程度"。一个堵死的十字路口,车排得再长,也不代表这些车在"高速行驶";恰恰相反,它们一寸都动不了。我过去把"长长的车队"误读成了"繁忙的车流",而真相是,那是一场彻底的瘫痪。这次最大的收获,是我学会了把"压力大"和"在做事",这两个我一直混为一谈的概念,彻底分开。一个高负载的信号,它只忠实地告诉你一件事:这里堆积了大量"卡住的东西"。但它【绝不】告诉你,这些东西是"忙着被处理",还是"堵着没人处理"。这两者,是天壤之别——前者你该去【增援算力】,后者你该去【疏通那个堵点】。我之前对着一个"堵死"的系统,满世界找那个"忙碌"的元凶,自然一无所获,因为元凶根本不忙,它只是个受害者,和其他二十个进程一起,被困在了那个真正的堵点——内存不够——的下游。所以下一次,当我再看到一个"压力很大"的信号——无论是一台机器的负载,还是一个团队积压的待办,还是一个人忙乱的状态——我不会再想当然地以为"它正在高效运转"。我会先冷静地追问一句:这堆积起来的压力,究竟是因为"事情多到做不完",还是因为"卡在了某个环节上,根本做不了"?因为很多时候,我们看到的"忙",根本不是忙,而是堵;而你若把一场瘫痪错当成一场繁忙,你就会一直在给一辆动不了的车,徒劳地踩着油门。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
Linux教程

sudo 每次都卡 30 秒才执行:一次 Linux 主机名解析超时的排查复盘

2026-5-20 23:26:58

Linux教程

能 ping 通网关却上不了外网:一次 Linux 路由表与默认网关的排查复盘

2026-5-20 23:40:07

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索