登录一台卡顿的服务器,多数人先敲 htop,屏幕顶部跳出一行 Load average: 0.48 0.34 0.19。这三个数是整台机器最显眼的指标,也是最常被误读的指标——有人看到 1.0 就紧张,有人看到 20 还觉得没到大碍。判断的基准其实只有一样东西:核数。这篇文章把统计定义、判读方法和 htop 的实操按顺序讲清,看完就能对着自己的服务器读数。
环境说明:Ubuntu 24.04 官方仓库自带 htop 3.3.0(apt-cache policy htop 可查),本文命令均在此版本验证可用。其他发行版的 htop 行为一致。
三个数的定义先搞对
load average 衡量的东西有明确定义:1、5、15 分钟内,处于「可运行」或「不可中断」状态的进程数的指数移动平均。可运行指在 CPU 上跑或排队等 CPU;不可中断(D 状态)指卡在磁盘 I/O 这类无法被信号打断的系统调用里。
把 D 状态算进负载,是 Linux 和其他 Unix 的分歧点。传统 Unix 只统计等 CPU 的进程,Linux 连等磁盘的也计进去——磁盘一卡,负载就涨,CPU 空着也一样。负载高不再等价于 CPU 忙,磁盘堵了它照样涨。 这正是后面 D 状态排查存在的意义。
默认视图只能看到均值,要看瞬时排队情况,/proc/loadavg 第四列更直接:
cat /proc/loadavg
# 0.48 0.34 0.19 2/319 2000451
# 均值×3 + 当前可运行/总进程数 + 最近分配的 PID
2/319 意思是 319 个进程里此刻只有 2 个在争 CPU。均值是历史曲线,这一列是现场。
判读只有一条基准线:核数
负载是「在忙的事」的数量,核数是「能干活的窗口」数量,两个数直接比。2 核机器负载 2.0,等于每个核头上都排着一个任务,恰好饱和;负载 4.0 就是一半任务在排队。
| 负载 ÷ 核数 | 系统状态 | 要不要处理 |
|---|---|---|
| < 0.7 | 有余量 | 不用 |
| 0.7 ~ 1.0 | 接近饱和 | 留意趋势 |
| 1.0 ~ 2.0 | 明显排队 | 找出吃 CPU 的进程 |
| > 2.0 | 严重过载 | 立即处理 |
三个时间窗的用法在趋势而不是绝对值。15 分钟均值高,说明过载已经持续了一刻钟以上;1 分钟均值高而 15 分钟低,多半是 cron、备份这类短时任务正常冲高。只盯 1 分钟均值做判断,最容易被尖刺骗到。
另一个常见误读是拿低配机器套标准。2 核 2G 的轻量云服务器,负载 1.5 已经在排队;32 核机器负载 3.0 连一半都没用上。先问核数,再读数字。
CPU 满、load 不高?问题在磁盘
负载和 CPU 使用率对不上的场景,最典型的是 CPU 闲着、负载却居高不下。这时候 htop 的 CPU 条大部分是绿色(低占用),负载却停在 2 以上——十有八九有进程卡在 D 状态等 I/O。
htop 里查 D 状态最快的路径:
- 按
F2进入设置 → Columns,把STATE列加进显示; - 按
F4过滤,输入D只看该状态的进程(F4 是固定字符串匹配,按 Esc 取消); - 选中可疑进程后按
s,直接挂上 strace 看它卡在哪个系统调用(需要装了 strace),按l用 lsof 列出它打开的文件。
D 状态进程的常见来源很集中:NFS 挂载对端失联、磁盘故障、flock 等待、慢速外置存储。看到一串 D 状态进程时,重点检查这几个方向,别急着杀进程——D 状态对信号免疫,kill 也杀不掉,只能等内核返回或修底层。
CPU 侧还有一个读数细节:htop 的 CPU% 列单进程上限是 100%,对应跑满一个核,2 核机器上吃满两个核的进程会显示 200%。要看「占全机比例」,在设置里把 CPU% 换成 NCPU%(按核数归一化),100% 就是全机跑满。两种读法混着看,容量规划会算错。
内存看 RES 和 M_SWAP,别被 VIRT 吓到
htop 顶部的内存条旁边常伴着一条绿色 swap 条。排内存问题,进程列表里三个列有用:
| 列 | 含义 | 用途 |
|---|---|---|
| VIRT | 虚拟内存总量 | 参考价值低,Java/数据库进程动辄几十 G,不代表真实占用 |
| RES | 常驻物理内存 | 判断真实占用的首选,MEM% 基于它算 |
| M_SWAP | 被换出到 swap 的页大小 | 直接显示谁被换出去了 |
按 M 键让列表按内存排序,RES 从高到低一目了然。哪个进程 M_SWAP 长期不为零,说明它冷数据被挤到 swap,内存压力已经真实发生。2G 小内存机器上这个信号比任何监控告警都直接。
OOM 风险也有现成读数:把 OOM 列加进视图,显示的就是内核 OOM killer 给每个进程算的分数——分数最高的进程,就是内存耗尽时第一个被内核杀掉的。提前知道谁排在第一,比事后查日志快。
日常盯盘只留这几下
htop 键位上百个,日常高频用的就一组:
htop -u www-data # 只看某个用户(Web 进程排查常用)
htop -t # 直接进树状视图,看父子关系
htop -p 1234,1235 # 只盯指定 PID
htop --readonly # 生产机只读模式,禁掉 kill/renice 误操作
进界面后的核心操作:
| 键 | 作用 | 场景 |
|---|---|---|
F4 | 增量过滤(固定字符串,` | ` 分隔多词) |
F5 | 树状视图 | 看清哪个父进程在反复拉起子进程 |
F6 | 换排序列(</> 快速切换) | CPU 换成内存、换 DISK R/W |
Space → F9 | 多选后批量发信号 | 批量 kill 一组 worker |
F | 跟随进程 | 排序变化时选中行跟着目标走 |
H / K | 隐藏用户态/内核线程 | 降噪,一屏只看进程 |
O | 隐藏容器内进程 | 宿主机视角只看宿主负载 |
两个配置层面的提醒。其一,调好的列布局和配色在正常退出(按 q)时写进 ~/.config/htop/htoprc,被信号杀掉就丢——SSH 断线可能正好触发这种情况,调完记得退干净再关窗口。其二,只想看一眼但不想误按键的生产机,--readonly 启动最稳妥,kill 和 renice 全部禁用。
常见问题
load average 多少算高?
除以核数再判读。2 核机器 2.0 就是饱和,16 核机器 2.0 才用了八分之一。脱离核数谈数值没有意义。
负载高但 CPU 使用率低,为什么?
D 状态进程在等 I/O。Linux 的负载均值把不可中断进程也算进去,磁盘一卡负载就涨。htop 过滤 D 状态找出元凶,方向查 NFS、磁盘故障和锁等待。
D 状态进程 kill -9 也杀不掉吗?
杀不掉。D 状态对一切信号免疫,只能等它卡住的系统调用返回。能做的排查是确认底层存储是否正常,或解除 NFS 卡住的挂载。
VIRT 占了几十 G,内存是不是要爆了?
不会。VIRT 是虚拟地址空间大小,包含映射但未触碰的内存,Java 和数据库进程普遍虚高。看 RES 和 MEM% 才是真实占用。
htop 顶部的 CPU 温度怎么打开?
F2 设置里开启温度显示即可,依赖 libsensors 库且机器有 coretemp 传感器,VPS 虚拟化环境通常读不到。
改动过的列布局重启后没了?
配置只在正常退出时写盘。被信号杀掉(含 SSH 断线)改动会丢,调整完按 q 退出一次,或用 HTOPRC 环境变量把配置存到指定路径。
负载是症状,D 状态是线索,核数是标尺——三个数读对,htop 剩下的键位都是细枝末节。服务器再卡,先看 2/319 那一列,再看核数,三十秒内就能判断该查 CPU 还是查磁盘。