当前位置:首页>Linux>每天学一个Linux命令系列(24):top/htop - CPU飙高谁搞的鬼?一眼定位

每天学一个Linux命令系列(24):top/htop - CPU飙高谁搞的鬼?一眼定位

  • 2026-10-11 07:02:38
每天学一个Linux命令系列(24):top/htop - CPU飙高谁搞的鬼?一眼定位
运
运维少年 · 科技观察

这个命令是干啥的

top 是 Linux 系统自带的任务管理器。实时显示所有进程的 CPU 和内存使用情况,还能排序、过滤、杀进程。

ps 是"拍一张照片",告诉你"此刻有哪些进程在跑"。top 是"一段录像",持续刷新,让你看到 CPU 和内存的实时变化。

我第一次用 top 是在公司服务器 CPU 飙到 100% 报警的时候。登录上去敲了个 top,回车一敲,就看到一个 PHP 进程的 CPU 列在 95% 左右晃动。回车确认 PID,直接 k 杀掉,全过程不到 10 秒。如果当时用 ps 查,找到 PID,再切出去执行 kill,多好几步。

htop 是 top 的升级版,界面更漂亮,能用鼠标操作,支持彩色显示。不过很多服务器默认没装,得自己 apt install htop 或者 yum install htop。

基本用法(3分钟上手)

top

# 直接输入 top
top

一进去你看到的是这个画面(简化版):

top - 10:15:23 up 30 days,  2:15,  1 user,  load average: 1.20, 0.80, 0.50
Tasks: 123 total,   2 running, 121 sleeping,   0 stopped,   0 zombie
%Cpu(s): 45.2 us,  8.5 sy,  0.0 ni, 45.1 id,  0.8 wa,  0.0 hi,  0.4 si,  0.0 st
MiB Mem :   7956.2 total,   1234.5 free,   3456.8 used,   3264.9 buff/cache
MiB Swap:   2048.0 total,   1800.0 free,    248.0 used.   4200.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1289 www-data  20   0  456890  65432  12340 S  45.2   0.8   2:34.56 nginx
 3421 mysql     20   0 1234567 234567  45678 S  12.3   2.9  45:23.12 mysqld
 5678 root      20   0  169740  13540   8932 S   2.1   0.2   0:12.34 sshd

最上面几行是系统概览,包含:当前时间、系统运行时间、登录用户数、load average(1分钟/5分钟/15分钟的平均负载)。

下面就是进程列表。按 q 退出。

top 的常用快捷键

在 top 运行界面里按:

按键作用
P按 CPU 占用排序(大写 P)
M按内存占用排序(大写 M)
1展开/折叠每个 CPU 核心的使用率
H切换到线程模式(看每个线程的 CPU 消耗)
k输入 PID 杀进程(会提示信号类型)
r调整进程优先级(renice)
c显示完整命令行
t切换 CPU/负载的图形条
m切换内存的图形条
W把当前配置写入 ~/.toprc 保存
q退出

这组快捷键里我天天用的就是 P、M、1 这三个,排查性能问题基本够了。

htop

# 如果系统没装
sudo apt install htop     # Debian/Ubuntu
sudo yum install htop     # CentOS/RHEL

# 启动
htop

htop 默认就有颜色区分(绿色表示进程的 CPU 占用,红黄表示内存),还能用鼠标点击排序。按 F9(或 F10)可以选择信号杀进程,按 F5 可以看树形结构。

我个人习惯是:公司电脑装 htop,远程服务器用 top(因为不一定有 htop 的安装权限)。

进阶骚操作

按 CPU 排序 + 按内存排序

top 启动之后:

# 启动 top
top

# 按大写 P(按 CPU 降序排列)
# 按大写 M(按内存降序排列)

这两个快捷键是 top 最重要的两个操作。我排查问题时的顺序:

1. 登录服务器,敲 top
2. 按 P 看哪个进程吃 CPU
3. 按 M 看哪个进程吃内存
4. 按 q 退出,决定怎么处理

查看每个 CPU 核心的使用率

# 启动 top 后按数字键 1
top

按 1 之后,顶部会从显示一个总的 CPU 使用率,变成显示每个核心的:

%Cpu0  : 50.2 us,  8.5 sy,  0.0 ni, 40.1 id,  0.8 wa,  0.0 hi,  0.4 si,  0.0 st
%Cpu1  : 30.1 us,  5.2 sy,  0.0 ni, 63.5 id,  0.8 wa,  0.0 hi,  0.4 si,  0.0 st

如果其中某些核心是 100%,其他核心是 0%,那很可能某个单线程应用把单核吃满了。这跟多核满载是两种不同的排查方向。

查看线程

# 按 H 切换到线程视图
top -H

# 或者
top   # 进去后按 H
# 指定只看某个进程的线程
top -H -p 1234

这对排查 Java 或者 Python 的多线程应用特别有用。你能看到哪个线程在"偷 CPU"。

load average 到底怎么看

top 顶部有一行:

load average: 1.20, 0.80, 0.50

这是 1分钟、5分钟、15分钟的平均负载。很多人以为是 CPU 利用率,其实不是。

平均负载 = 正在运行 + 等待运行的进程数。

怎么看这个数字?

  • ·单核 CPU:load average 超过 1.0 说明 CPU 饱和了
  • ·4 核 CPU:load average 超过 4.0 说明 CPU 饱和了
  • ·如果 1 分钟远大于 15 分钟:负载在上升,刚出事
  • ·如果 1 分钟小于 15 分钟:负载在下降,正在恢复

比如一个 4 核服务器,load average 3.5,看起来很高,但实际 CPU 还没满载(3.5 < 4)。如果 load average 到 8,那就是确实排队了。

批量模式(用于采集数据做报表)

# 只输出一次结果,不用交互界面
top -b -n 1

# 每小时采集一次,共采集 3 次
top -b -n 3 -d 3600 > /tmp/cpu_report.txt
# 批量模式 + 自定义列,采集到日志文件
top -b -n 1 -o %CPU -e k | head -20 > /var/log/cpu_top_$(date +%Y%m%d_%H%M).log

配合 crontab 可以实现定时采集 CPU 数据:

# 每 5 分钟采样一次 CPU 排名靠前的进程
*/5 * * * * top -b -n 1 -o %CPU | head -12 >> /var/log/top_cpu.log

top 的过滤功能

# 只显示某个用户的进程
top -u mysql

# 只显示特定 PID
top -p 1234,5678
# 交互模式下按 u 然后输入用户名
top
# 按 u
# 输入 mysql
# 回车

避坑指南

1. CPU 使用率 vs 平均负载,是两码事

很多人把 top 里的 %Cpu(s) 和 load average 搞混。

CPU 使用率高:有一个或多个进程在大量计算。10% CPU 使用率说明 CPU 很闲。

平均负载高:即使 CPU 使用率只有 20%,平均负载可能很高。因为进程在等待磁盘 I/O 或者网络。

比如:
- CPU 使用率 20%,load average 8.0:进程在等磁盘(I/O 瓶颈,最常见的是数据库)
- CPU 使用率 90%,load average 9.0:CPU 确实不够用(需要升级服务器或者优化代码)

2. 别只看 %CPU,也得看 wa(I/O Wait)

top

看这行:

%Cpu(s):  5.2 us,  1.5 sy,  0.0 ni, 20.1 id, 70.8 wa,  0.0 hi,  2.4 si,  0.0 st

wa 是 70.8%。这意味着 CPU 在花 70% 的时间等待磁盘 I/O。这时候程序慢不是 CPU 不够,是磁盘太慢了。

我之前遇到过一个 case:应用响应很慢,top 一看 CPU 使用率才 8%,但 wa 占了 60%。用 iotop 查出来是某个备份脚本在大量读写磁盘,等备份跑完就好了。

3. top 的 %MEM 和 free 显示的不一定一致

top 里的 %MEM 是「该进程占物理内存的百分比」。而系统内存使用量(used)包括 buffer/cache,这两个是不同的概念。

4. htop 用颜色吓唬人

htop 默认把进程 CPU 使用率用颜色标出来:绿色是普通,黄色有一定负载,红色就是快满了。但我发现很多人看到 htop 有几个红色条就慌了,其实每个核心整体使用率还是要看百分比数字,颜色仅供参考。

实战场景(重点!结合真实运维场景)

场景一:CPU 飙高报警,10 秒定位

收到 Zabbix 告警:CPU 使用率超过 90%。

# SSH 登录服务器
ssh deploy@prod-server

# 直接 top
top

进去后做这几步:

1. 按 P(大写),按 CPU 降序排列
2. 看到最上面那个进程,记下 PID
3. 按 1,看是所有核心都高还是单个核心高
4. 按 c,看完整命令行,确认是什么程序
5. 按 k,输入 PID,信号默认 15(SIGTERM),回车

整个过程 10 秒搞定。

场景二:top 采集数据写报告

线上每台服务器做一个周报,看一周 CPU 和内存的趋势:

#!/bin/bash
# 每周一采集 CPU 数据
LOG_DIR="/var/log/perf"
mkdir -p $LOG_DIR

echo "=== $(date) ===" >> $LOG_DIR/cpu_$(date +%Y%W).log

# 采集系统概览
top -b -n 1 | head -5 >> $LOG_DIR/cpu_$(date +%Y%W).log

# 采集前 10 名进程
top -b -n 1 -o %CPU | head -17 >> $LOG_DIR/cpu_$(date +%Y%W).log

echo "---" >> $LOG_DIR/cpu_$(date +%Y%W).log

配合 cron 每 5 分钟采样一次:

# crontab 每 5 分钟采集一次
*/5 * * * * /usr/local/bin/cpu_collect.sh

数据多了之后,导入到 Excel 或者 Grafana 里画图,能看到明显的趋势。

场景三:I/O 瓶颈导致响应慢

用户反馈网页响应很慢,登录服务器看:

# top 看一眼
top

发现:

%Cpu(s):  3.2 us,  1.5 sy,  0.0 ni, 15.1 id, 78.8 wa,  0.0 hi,  1.4 si,  0.0 st

wa 占 78.8%!磁盘在拼命干活。

# 按 P 看看哪个进程 CPU 占最多
# 运行 mysql,那可能是数据库查询太慢
# 运行 dd/rsync 之类,那是备份脚本在抢磁盘

用 iostat 进一步确认:

# 看磁盘 I/O 负载
iostat -x 1 5

如果是备份脚本导致的,调低备份速度,或者换到半夜跑。

场景四:top 结合 watch 做实时监控

# 每 2 秒刷新一次,按 CPU 排序显示前 10 个进程
watch -n 2 'top -b -n 1 -o %CPU | head -17'
# 只看 MySQL 进程的实时情况
watch -n 1 'top -b -n 1 -p $(pgrep -d, -x mysqld)'

这个组合在你调试某个服务的时候特别好用。比如改了 Nginx 配置重载后,看看 worker 进程的 CPU 变化。

今日作业(一道小题目)

题目:你接到报警说某台线上服务器的 CPU 超过 90%,SSH 上去排查。

要求写出:
1. 你登录后敲的第一条命令(启动 top)
2. 进去后你按哪个快捷键(说明原因和看到什么)
3. 如果发现是某个进程搞的,怎么杀掉它(在 top 里操作)
4. 如果 top 显示 CPU 使用率很低(比如 15%)但系统还是很慢,该看哪些指标(写 2-3 个 CPU 状态列)

。

E N D

运维少年 · 科技观察

最新文章

随机文章