top / htop —— 实时进程资源监控
一句话定义
top 是 Linux 自带的实时进程监控工具,每 3 秒(可调)刷新一次,按 CPU 占用降序显示。htop 是更易用的现代替代——彩色、可滚动、可点击操作,多数发行版要 apt install htop 装。
典型场景
- 节点 load 高 / CPU 飙了:
top看哪个进程 - 内存被吃光:
top按内存排序 - 找烧 CPU 的线程:
top -H -p <PID> - 一次性看:"是不是真有进程在跑、还是 ssh 都登不上":
top -b -n 1 - htop 的 F5 树形视图:看进程父子关系
top 默认界面
top - 14:30:00 up 5 days, 1:23, 2 users, load average: 1.50, 1.20, 0.80
Tasks: 245 total, 2 running, 243 sleeping, 0 stopped, 1 zombie
%Cpu(s): 12.5 us, 3.0 sy, 0.0 ni, 83.5 id, 0.5 wa, 0.5 hi, 0.0 si, 0.0 st
MiB Mem : 16000 total, 500 free, 12000 used, 3500 buff/cache
MiB Swap: 0 total, 0 free, 0 used. 3000 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 root 20 0 500000 80000 20000 R 50.0 0.5 5:23.45 nginx
5678 root 20 0 1200000 300000 10000 S 10.2 1.9 2:15.30 python
9012 root 20 0 100000 20000 5000 S 2.0 0.1 0:30.12 sshd
顶部摘要(信息量最大)
第 1 行:
top - 14:30:00 up 5 days, 1:23, 2 users, load average: 1.50, 1.20, 0.80
up 5 days—— 系统启动后的运行时间load average—— 1 / 5 / 15 分钟的平均负载
load average 不是 CPU 利用率!它是"可运行 + D 状态进程数"的平均。
- 在 N 核机器上,load = N 表示 CPU 满载
- load > N 表示有进程在等
- 单纯看 load 数字没意义,要除以核数:
load / nproc
第 2 行:进程数量统计
Tasks: 245 total, 2 running, 243 sleeping, 0 stopped, 1 zombie
zombie > 0 要查(ps.md 找 STAT=Z)。
第 3 行:CPU 状态(最重要)
%Cpu(s): 12.5 us, 3.0 sy, 0.0 ni, 83.5 id, 0.5 wa, 0.5 hi, 0.0 si, 0.0 st
| 缩写 | 含义 | 高代表什么 |
|---|---|---|
us | user:用户进程 CPU | 应用在烧 CPU |
sy | system:内核态 CPU | 系统调用 / 内核工作多 |
ni | nice:被降优先级的用户进程 | 不重要 |
id | idle:空闲 | 这才是"空" |
wa | I/O wait:等磁盘 | 磁盘瓶颈或网络存储慢 |
hi | hardware interrupt:硬中断 | 网卡很忙 / 硬件问题 |
si | software interrupt:软中断 | 通常 net / timer |
st | steal:被 hypervisor 偷走 | 虚拟机被宿主超卖 |
排错信号:
us高 → 应用问题(哪个进程吃 CPU)sy高 → 系统调用密集,可能内核版本 bug 或锁竞争wa高 → 磁盘 I/O 瓶颈st高 → 你这虚拟机被宿主机超卖了(云厂商问题,凡人无能为力)
第 4-5 行:内存
MiB Mem : 16000 total, 500 free, 12000 used, 3500 buff/cache
MiB Swap: 0 total, 0 free, 0 used. 3000 avail Mem
total—— 总内存free—— 完全空闲used—— 已使用buff/cache—— 内核缓存(可以快速释放)avail Mem—— 真正可用(free + 可回收的 buff/cache,这是真实指标)
不要看
free直接判断"内存不够"。Linux 主动用空闲内存做 buffer/cache。看avail Mem:低于 10% 才算真紧张。
K8s 节点上 swap 通常为 0(kubeadm 强制要求)。
top 交互按键(学会这几个就够)
| 键 | 作用 |
|---|---|
q | 退出 |
h / ? | help |
1 | 切换"按核心展开" CPU 行 |
M | 按内存排序(大写) |
P | 按 CPU 排序(默认) |
T | 按累计 TIME 排序 |
c | 切换显示完整命令行 / 简短 |
H | 切换显示线程 |
k | 杀进程(提示输入 PID + signal) |
r | renice 进程 |
f | 选择显示哪些列 |
o | 添加过滤(如 COMMAND=nginx) |
u | 按用户过滤 |
W | 保存当前布局到 ~/.toprc |
space | 立刻刷新 |
d | 改刷新间隔 |
最常用 4 个:
1 - 看多核 CPU 分布
M - 按内存排序
c - 看完整命令行
q - 退出
top 命令行 flag
top -b # batch 模式(不交互、输出到 stdout)
top -b -n 1 # 跑一次就退出
top -d 1 # 1 秒刷新(默认 3 秒)
top -u nginx # 只显示 nginx 用户
top -p 1234,5678 # 只显示指定 PID
top -H -p 1234 # 看进程 1234 的所有线程
batch 模式(脚本 / 监控用)
top -b -n 1 | head -20 # 单次快照
top -b -n 5 -d 1 > /tmp/top.log # 每秒一次,跑 5 次写文件
监控告警里抓 top 输出当作"故障现场"留证据:
# 系统报警时执行
(
echo "=== top ==="
top -b -n 1 | head -30
echo "=== ps top 20 by cpu ==="
ps aux --sort=-%cpu | head -20
echo "=== iostat ==="
iostat -xz 1 5
) > /tmp/incident-$(date +%F-%H%M).log
看线程:-H 或在 top 里按 H
top -H -p 1234
# 每行是一个线程,不是进程
Java / 多线程应用排错:
# 1. 找烧 CPU 的进程
top # PID 1234 占 200% CPU(多核)
# 2. 看线程
top -H -p 1234
# 看到 SPID=1289 占 80%
# 3. 转 16 进制(jstack 用)
printf "%x\n" 1289
# 509
# 4. 在 java 里查这个线程
jstack 1234 | grep -A 10 'nid=0x509'
htop —— 现代 top
apt install -y htop
htop
htop 比 top 好的地方:
- 彩色 + 进度条:CPU / 内存可视化
- 可左右滚动:完整命令行不截断
- 可滚动选择:上下键选进程
- 树形视图(F5):看父子关系
- F9 kill:图形化选信号
- F6 排序:弹出列表选哪列排
- F4 过滤:模糊搜索
htop 默认布局
1 [||| 5.0%] Tasks: 245, 678 thr; 2 running
2 [||||| 8.3%] Load avg: 1.50 1.20 0.80
3 [|| 3.0%] Uptime: 5 days, 1:23
4 [||| 5.0%]
Mem[||||||||||||||| 12G/16G]
Swp[ 0/0]
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
1234 root 20 0 500M 80M 20M R 50.0 0.5 5:23.45 nginx
5678 root 20 0 1.2G 300M 10M S 10.2 1.9 2:15.30 python
htop 常用快捷键
| 键 | 作用 |
|---|---|
| F1 | help |
| F2 | setup(改显示) |
| F3 | search |
| F4 | filter |
| F5 | 树形视图(强烈推荐) |
| F6 | 排序方式 |
| F9 | kill |
| F10 / q | 退出 |
t | 树形开关 |
H | 显示线程开关 |
K | 显示内核线程 |
看磁盘 I/O:iotop
top 不显示磁盘 I/O。要看哪个进程在烧磁盘:
apt install -y iotop
iotop # 类似 top 但显示磁盘 I/O
iotop -o # 只显示有 I/O 的进程
iotop -b -n 1 # batch 模式
K8s 节点上 etcd / containerd / journald 是 I/O 大户。
实战场景
1. 节点 load 飙到 50(4 核机器)
top
# load average: 50, 45, 30
# %Cpu(s): 100 us / 0 sy / 0 id ← 应用烧 CPU
# 看哪个进程
M / P # 按内存 / CPU 排序
# 或者
ps aux --sort=-%cpu | head -10
2. wa(IO wait)持续高
top
# %Cpu(s): 5 us / 1 sy / 70 wa ← 在等磁盘
iotop -o # 哪个进程在 I/O
# 看到 etcd 在猛写
# 或者
iostat -xz 1 5 # 看磁盘 util
# %util 90+ 持续 → 磁盘瓶颈
# 看 D 状态进程
ps aux | awk '$8 ~ /D/'
3. 内存被吃光
top
# avail Mem 100 MB ← 紧张
# 按内存排
top # 按 M
# 找到大户
# 看是不是 OOM 风险
dmesg -T | tail -50 | grep -i 'oom\|memory'
# 看 [oom-kill] 记录
4. st(steal)持续高
top
# %Cpu(s): ... 30 st ← 被宿主机偷走 30% CPU
虚拟机被宿主超卖。你能做的不多:
- 联系云厂商升级 / 换实例
- 工作负载 migrate 到别的机器
- 阿里云上是预付费实例就找客服 / 抢迁移
htop 配置文件 ~/.config/htop/htoprc
htop 的列、颜色、排序方式都可以持久化。F2 setup 里改完,自动保存到 ~/.config/htop/htoprc。
服务器之间同步:scp 这个文件过去。
常见踩坑
坑 1:%CPU > 100%
%CPU
198.0 ← 进程占 2 个核
多核系统下 %CPU 是"占了多少核"。200% = 2 核满载。-1 按下让 top 切到"按核心展开"模式,CPU 行变成多行(每核一行)。
坑 2:free 几乎为 0,但系统正常
Mem : 16000 total, 100 free, 8000 used, 7900 buff/cache
free 只是"完全没人用的内存"。buff/cache 可以马上回收。看 avail Mem ——这是真实"还能用的"。
坑 3:在 K8s pod 里跑 top 看到全节点的资源
kubectl exec my-pod -- top
# 看到的 CPU / 内存是节点全部,不是 pod 限额
容器里的 top 默认看 宿主视角(共享 procfs)。要看 pod 真实限额:
# 看 pod 的 cgroup 限额
cat /sys/fs/cgroup/memory/kubepods/.../my-pod/memory.limit_in_bytes
# 看 pod 实际用了多少
cat /sys/fs/cgroup/memory/kubepods/.../my-pod/memory.usage_in_bytes
或者用 kubectl top pods(要 metrics-server)。
新版 cgroup v2 + containerd 配 host pid namespace 隔离能让 top 看到 pod 视角,但默认不开。
坑 4:load average 高但 CPU 不忙
load average: 30, 25, 20
%Cpu(s): 5 us, 90 id ← CPU 90% 空闲,但 load 30
load 包含 D 状态进程(等 I/O)。看 D 数:
ps aux | awk '$8 ~ /D/' | wc -l
# 30
很多 D 状态 = 磁盘 / 网络存储卡住,CPU 反而闲着。
坑 5:htop 看不见 root 进程(普通用户)
普通用户跑 htop 默认只看自己进程。sudo htop 看全部。
坑 6:top -b 输出含 ANSI 控制字符
top -b -n 1 > /tmp/top.log
cat /tmp/top.log
# 一堆 ESC[... 颜色码
加 --:
top -b -n 1 -w 200 | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' > /tmp/top.log
或者直接 redirect 而不是用某些 batch 行为。
坑 7:刷新太快看不清
top # 默认 3 秒一次
top -d 0.5 # 0.5 秒一次(眼睛跟不上)
排查瞬时尖峰可以 1 秒一次(top -d 1),但太快反而看不清。htop 默认 1-2 秒。
坑 8:服务器没装 htop
$ htop
htop: command not found
很多生产服务器精简镜像没装。apt install htop。
不能装的话用 top —— 功能够了,就是难看。