第29章:Linux 性能命令实战手册
top/vmstat/iostat/sar/netstat/ss/lsof/dstat——压测时必看的系统指标
压测报告说"P95 响应时间 1200ms,TPS 只有 200",但测试负责人问你:"是服务器撑不住了,还是代码有问题?"你打开服务器,看到一堆终端命令,不知道从哪看起。
这一章是你在服务器上查问题的"武器库"。不是所有命令都要记住,但遇到高 CPU、高内存、高 IO 各种情况时,你要知道该用什么命令看什么指标。
为什么压测时必须监控服务器
压测工具只能告诉你"从客户端视角看,请求慢了",但不能告诉你"为什么慢"。服务器监控给你另一半信息:
- CPU 使用率 90%?可能是代码计算密集,或者 GC 频繁
- 内存使用率 95%?可能是内存泄漏,或者 JVM 堆设太小
- 磁盘 IO %util 100%?可能是大量日志写入,或者 MySQL 慢查询打爆磁盘
- 网络连接 TIME_WAIT 几千个?可能是连接没复用,短连接太多
top 命令详解
top 是最常用的实时监控命令,每 3 秒刷新一次。
top -b -n 1 # 非交互模式输出一次(适合截图和脚本)
top # 交互模式(实时刷新)
关键区域解读:
top - 10:23:45 up 5 days, 12:30, 2 users, load average: 2.34, 1.89, 1.56
Tasks: 312 total, 2 running, 310 sleeping, 0 stopped, 0 zombie
%Cpu(s): 45.2 us, 8.3 sy, 0.0 ni, 44.1 id, 1.8 wa, 0.0 hi, 0.6 si, 0.0 st
MiB Mem : 15896.3 total, 1234.5 free, 12456.7 used, 2205.1 buff/cache
MiB Swap: 2048.0 total, 1890.2 free, 157.8 used. 2056.3 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
12345 app 20 0 8.2g 3.1g 45000 S 89.3 20.1 45:23.12 java
789 mysql 20 0 2.1g 800000 12000 S 15.2 4.9 8:45.67 mysqld
load average 三个数字:过去 1 分钟、5 分钟、15 分钟的平均负载。数字 = CPU 核心数时,系统刚好满载;超过核心数,说明有任务在等待 CPU。比如 4 核机器,load average 显示 4.5,就说明系统过载了。
CPU 各列含义:
us(user):用户态 CPU 使用率,你的应用代码消耗的sy(system):内核态 CPU,系统调用、IO 操作等wa(iowait):等待 IO 完成的时间,超过 30% 就要警惕磁盘瓶颈si(softirq):软中断,网络包处理,高并发网络场景会高
内存各列:
buff/cache:文件系统缓存,这部分内存在需要时可以释放,不是真正的"占用"avail Mem:实际可用内存(free + 可回收的 buff/cache),这个才是判断内存是否紧张的指标
进程列表关键列:
%CPU:进程 CPU 使用率(多核时可以超过 100%,200% 表示占满了 2 个核)RES:实际使用的物理内存(Resident Set Size)S:进程状态(S=sleeping, R=running, D=不可中断睡眠/通常在等IO, Z=僵尸)
top 常用交互命令:
1:展开各 CPU 核心的使用情况(看是否负载不均衡)
vmstat:系统整体健康度
vmstat 每隔指定秒数输出一行,非常适合压测时持续监控:
vmstat 1 # 每秒刷新一次
vmstat 1 60 # 每秒刷新,共输出 60 行(监控 1 分钟)
输出示例:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 1 15800 234567 123456 2345678 0 1 10 450 2345 8901 45 8 44 2 0
2 0 15800 234100 123456 2345678 0 0 0 890 2456 9012 48 9 41 1 0
每列含义(重要的加粗):
| | |
|---|
r | | 超过 CPU 核数说明 CPU 瓶颈 |
b | | |
swpd | | 不为 0 就警惕,频繁 swap 会导致性能急剧下降 |
free | | |
si | | 不为 0 说明内存严重不足 |
so | | 不为 0 是大问题 |
bi | | |
bo | | |
in | | |
cs | | 过高说明线程切换频繁,可能线程数太多 |
us/sy/id/wa | | |
典型异常模式:
iostat:磁盘 IO 详情
vmstat 只给磁盘 IO 的粗略数字,iostat 能看到每块磁盘的详细情况:
iostat -x 1 # 每秒输出扩展信息
iostat -x 1 30 # 每秒输出,共 30 次
关键输出:
Device r/s w/s rkB/s wkB/s await svctm %util
sda 12.3 89.5 234.5 1234.5 45.6 3.2 78.9
nvme0n1 2.1 15.3 45.2 234.1 3.2 0.8 5.6
| | |
|---|
r/s | | |
w/s | | |
rkB/s | | |
wkB/s | | |
await | | HDD < 20ms,SSD < 5ms,超过警惕 |
svctm | | |
%util | | 接近 100% 说明磁盘成为瓶颈 |
%util 是最重要的指标。HDD 的 %util 超过 80% 就会影响性能;SSD 由于支持并发,即使 %util 100% 也不一定是瓶颈(但 await 会升高)。
netstat / ss:查看网络连接状态
压测时 TCP 连接状态是重要信息,尤其是 TIME_WAIT 过多的问题:
# 查看各种 TCP 状态的连接数统计
ss -s
# 输出:
# Total: 1234
# TCP: 892 (estab 456, closed 123, orphaned 23, timewait 234)
# 查看 ESTABLISHED 连接详情
ss -tnp state established
# 统计各状态连接数(经典命令)
ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn
# 或者用 netstat
netstat -an | awk '/^tcp/ {print $6}' | sort | uniq -c | sort -rn
TCP 连接状态的含义:
TIME_WAIT:连接关闭后的等待状态(默认等 60 秒),大量 TIME_WAIT 说明短连接太多CLOSE_WAIT:服务端没有正确关闭连接,可能有连接泄漏SYN_RECV:半开连接,大量时可能是 SYN Flood 攻击
TIME_WAIT 过多怎么处理:
# 查看当前 TIME_WAIT 数量
ss -s | grep timewait
# 如果压测时 TIME_WAIT > 10000,考虑开启 TCP 复用
echo"net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf
sysctl -p
dstat:综合监控神器
dstat 是最好用的综合监控工具,把 vmstat + iostat + netstat 的信息整合到一行里:
# 安装
apt install dstat # Ubuntu/Debian
yum install dstat # CentOS/RHEL
# 运行
dstat -cdngy 1 # 每秒输出:CPU、磁盘、网络、换页、系统
dstat -cdngy --top-cpu --top-mem 1 # 加上最耗 CPU 和内存的进程
输出示例:
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
45 8 44 2 0 1| 45k 890k| 234k 123k| 0 0 |2345 8901
48 9 41 1 0 1| 0 1.2M| 345k 234k| 0 0 |2456 9012
所有指标一目了然,比切换多个命令方便得多。压测时开着 dstat 是很好的习惯。
sar:历史数据查看
如果你想看压测结束后某个时间段的历史数据(top 和 dstat 是实时的,结束就没了),用 sar:
# 查看今天的 CPU 历史数据(每 10 分钟一条)
sar -u
# 查看特定时间段
sar -u -s 10:00:00 -e 11:00:00
# 查看内存
sar -r
# 查看磁盘 IO
sar -d
# 查看网络
sar -n DEV
sar 需要 sysstat 服务在后台收集数据:
apt install sysstat
systemctl enable sysstat
systemctl start sysstat
压测时高指标意味着什么
快速诊断指南:
高 CPU(us > 80%):
- Java 应用:可能是频繁 GC、CPU 密集计算
- 检查:
jstack <pid> 查看线程状态,jstat -gcutil <pid> 1000 看 GC 频率
高 CPU(sy > 30%):
- 系统调用太多,可能是频繁的锁竞争、上下文切换(cs 也会高)
高 CPU(wa > 20%):
- 应用在等待 IO,进一步看
iostat 确认是哪块磁盘 - 可能是大量日志写入、MySQL 慢查询、缺少索引导致全表扫描
高内存(avail Mem < 总内存 10%):
- Java 应用:
jmap -histo <pid> 看堆内存占用分布
高磁盘 IO(%util > 80%):
- 查日志写入:
lsof -p <pid> | grep log - MySQL 检查慢查询:
SHOW PROCESSLIST
大量 TIME_WAIT:
本章小结
压测时的服务器监控,记住这个优先级:
dstat -cdngy 1 —— 先看综合信息,判断是 CPU / 内存 / IO / 网络哪个维度有问题iostat -x 1 / ss -s —— 深入看磁盘 IO 或网络连接状态
掌握了这些命令,当压测结果不好看时,你不再只会说"系统慢了",而是能说出"服务器 wa 高达 35%,是磁盘 IO 瓶颈,主要是 MySQL 的写操作"——这才是真正有价值的分析。