这个命令是干啥的
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 状态列)
。