性能分析工具
性能分析的核心不是工具本身,而是对系统运行原理的掌握。工具只是帮你更快观测到需要的指标。本文按 CPU/内存/IO/网络四个维度整理常用工具,并给出 USE 方法论作为分析框架。
目录
| 章节 | 说明 |
|---|---|
| 性能分析方法论 | USE 方法:利用率/饱和度/错误率 |
| CPU 性能工具 | top/htop/perf/mpstat/pidstat |
| 内存性能工具 | free/vmstat/sar/smem |
| IO 性能工具 | iostat/iotop/lsof/dstat |
| 网络性能工具 | netstat/ss/iftop/tcpdump |
| 系统调用追踪 | strace/ltrace/perf trace |
| 火焰图生成 | CPU/内存/Off-CPU 火焰图 |
| 综合分析流程 | 从现象到根因的排查步骤 |
性能分析方法论
USE 方法(Brendan Gregg)
对每个资源(CPU、内存、磁盘、网络),检查三个维度:
| 维度 | 含义 | 判断标准 |
|---|---|---|
| Utilization(利用率) | 资源繁忙时间占比 | CPU > 80% 需关注 |
| Saturation(饱和度) | 资源过载程度(等待队列长度) | 有等待队列即饱和 |
| Errors(错误率) | 错误事件数量 | 任何错误都需关注 |
分析顺序:先看 Errors(最严重),再看 Saturation(性能瓶颈),最后看 Utilization(趋势)。
性能分析思路
1. 确认现象:响应慢/CPU 高/OOM/磁盘满...
↓
2. 收集基线数据:top/free/iostat/netstat
↓
3. 缩小范围:确定是 CPU/内存/IO/网络 哪个维度
↓
4. 定位进程:找到消耗资源最多的进程(pidstat/top)
↓
5. 定位代码:perf/strace/火焰图 找热点函数
↓
6. 修复验证
CPU 性能工具
top — 实时概览
top
# 常用交互键:
# P 按 CPU 使用率排序
# M 按内存使用率排序
# 1 展开显示每个 CPU 核心
# H 显示线程(而非进程)
# k kill 进程
# 非交互模式(采集 3 次,间隔 1 秒)
top -b -n 3 -d 1
关键字段解读:
| 字段 | 含义 |
|---|---|
| us | 用户态 CPU 占比 |
| sy | 内核态 CPU 占比(高说明系统调用频繁) |
| ni | nice 值调整的进程 CPU 占比 |
| id | 空闲 CPU |
| wa | I/O 等待(高说明磁盘/网络 I/O 是瓶颈) |
| hi | 硬中断 |
| si | 软中断(高说明网络收包压力大) |
| st | 虚拟机被宿主机抢占的 CPU |
htop — 增强版 top
htop
# 支持鼠标操作、树形显示进程、彩色 CPU 使用率条
# F5 树形视图,F6 排序,F9 发送信号
mpstat — 多核 CPU 统计
# 每秒输出所有 CPU 核心使用率
mpstat -P ALL 1
# 只看 CPU 0
mpstat -P 0 1 5 # 间隔 1 秒,共 5 次
pidstat — 进程级 CPU/IO 统计
# 每秒显示 CPU 使用率最高的进程
pidstat 1
# 显示特定进程的 CPU 使用
pidstat -p <pid> 1
# 显示进程的 IO 统计
pidstat -d 1
# 显示线程级别
pidstat -t -p <pid> 1
perf — 性能分析利器
# 全系统 CPU 热点(采样 30 秒)
perf top -g
# 采集特定进程
perf record -g -p <pid> -- sleep 30
perf report
# 统计系统调用次数
perf stat -e syscalls:sys_enter_read,syscalls:sys_enter_write -p <pid>
# 查看 CPU 缓存命中率
perf stat -e cache-references,cache-misses -p <pid> sleep 10
分析 Java 程序(需要 perf-map-agent):
# 生成 Java 符号表
java -agentpath:/path/to/libperfmap.so -jar app.jar &
perf record -g -p <pid> -- sleep 30
perf report
平均负载(Load Average)
uptime
# 输出:load average: 1.23, 1.45, 1.67(1分钟/5分钟/15分钟)
# 含义:处于运行状态(R)和不可中断状态(D)的进程数平均值
# 判断:负载 > CPU 核心数 × 70% 时需关注
内存性能工具
free — 内存概览
free -h # 人类可读格式
free -m # 以 MB 为单位
# 输出示例:
# total used free shared buff/cache available
# Mem: 16Gi 4.2Gi 8.1Gi 256Mi 3.7Gi 11Gi
# Swap: 2.0Gi 0B 2.0Gi
available 才是真正可用内存(包含可回收的 buff/cache)。
vmstat — 虚拟内存统计
vmstat 1 # 每秒输出一次
vmstat 1 10 # 共输出 10 次
# 关键字段:
# r 运行队列(等待 CPU 的进程数)
# b 不可中断睡眠进程数(I/O 等待)
# swpd 已使用的 Swap
# si Swap 换入速率(KB/s)
# so Swap 换出速率(KB/s)非 0 说明内存不足
# bi 块设备读取速率
# bo 块设备写入速率
# in 每秒中断数
# cs 每秒上下文切换数
sar — 系统活动报告
# 内存使用历史(每 1 秒,共 10 次)
sar -r 1 10
# 查看 Swap 使用
sar -W 1 10
# 查看历史数据(/var/log/sysstat/)
sar -r -f /var/log/sysstat/sa$(date +%d)
/proc/meminfo 详细内存信息
cat /proc/meminfo
# 关键字段
grep -E "MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree|Dirty|Writeback|Slab" /proc/meminfo
IO 性能工具
iostat — 磁盘 I/O 统计
# 每秒显示磁盘 I/O 统计
iostat -xz 1
# 关键字段:
# r/s 每秒读请求数
# w/s 每秒写请求数
# rkB/s 每秒读取 KB 数
# wkB/s 每秒写入 KB 数
# await I/O 平均延迟(ms)正常 < 10ms,> 100ms 需关注
# %util 磁盘繁忙程度(接近 100% 说明磁盘是瓶颈)
# svctm 平均服务时间(已废弃,不可靠)
iotop — 进程级 I/O 监控
# 需要 root 权限
iotop -o # 只显示有 I/O 活动的进程
iotop -b -n 3 # 批处理模式,采集 3 次
lsof — 列出打开的文件
# 查看进程打开的所有文件(含 Socket)
lsof -p <pid>
# 查看谁在使用某个文件
lsof /var/log/app.log
# 查看所有网络连接
lsof -i
# 查看某端口的进程
lsof -i :8080
# 查找已删除但仍被占用的文件(导致磁盘空间无法释放)
lsof | grep deleted
dstat — 综合实时统计
# 综合显示 CPU/磁盘/网络/内存
dstat -cdngy 1
# 显示最消耗 CPU 和 IO 的进程
dstat --top-cpu --top-io 1
网络性能工具
ss — Socket 统计(推荐,比 netstat 快)
# 显示所有 TCP 连接
ss -tnp
# 显示监听端口
ss -tlnp
# 按状态过滤
ss -tnp state established
ss -tnp state time-wait
# 统计各状态连接数
ss -s
# 查看 TCP 连接的详细信息(发送缓冲区、接收缓冲区)
ss -tnpi
netstat — 网络状态(老工具,已逐步被 ss 替代)
# 查看监听端口和进程
netstat -tlnp
# 查看所有连接状态统计
netstat -s
# 统计 TCP 各状态连接数
netstat -an | awk '/^tcp/{print $6}' | sort | uniq -c | sort -rn
iftop — 实时网络带宽
# 需要 root 权限
iftop -i eth0 # 监控 eth0 接口
iftop -n # 不解析 DNS(更快)
tcpdump — 抓包分析
# 抓取 eth0 上的 HTTP 流量
tcpdump -i eth0 port 80 -w /tmp/http.pcap
# 抓取特定 IP 的流量
tcpdump -i eth0 host 192.168.1.100
# 实时显示(不写文件)
tcpdump -i eth0 port 8080 -A -n
# 抓取 DNS 查询
tcpdump -i eth0 port 53
# 分析 pcap 文件(用 Wireshark 或 tcpdump 读取)
tcpdump -r /tmp/http.pcap -A | head -100
ping / traceroute — 网络连通性
# 基本连通性测试
ping -c 4 google.com
# 路由追踪
traceroute google.com
mtr google.com # 实时路由追踪(推荐)
# 测试 TCP 端口连通性
telnet host 8080
nc -zv host 8080
系统调用追踪
strace — 追踪系统调用
# 追踪进程的所有系统调用
strace -p <pid>
# 统计各系统调用耗时
strace -c -p <pid>
# 追踪特定系统调用(只看 read/write)
strace -e trace=read,write -p <pid>
# 追踪子进程
strace -f -p <pid>
# 保存到文件
strace -o /tmp/trace.log -p <pid>
常见用途:
- 排查程序启动慢(看哪些文件 open 失败)
- 排查 I/O 异常(看 read/write 的 fd 和返回值)
- 排查网络问题(看 connect/send/recv)
ltrace — 追踪库函数调用
ltrace -p <pid>
ltrace -c -p <pid> # 统计模式
perf trace — 性能版 strace
# 比 strace 开销小,适合生产环境
perf trace -p <pid>
perf trace -e read,write -p <pid>
火焰图生成
火焰图(Flame Graph)直观展示 CPU 时间分布,x 轴宽度代表占用时间,y 轴代表调用栈深度。
CPU 火焰图(On-CPU)
# 1. 采集数据(30 秒)
perf record -F 99 -g -p <pid> -- sleep 30
# 或全系统
perf record -F 99 -ag -- sleep 30
# 2. 生成折叠栈
perf script | /path/to/FlameGraph/stackcollapse-perf.pl > out.folded
# 3. 生成 SVG
/path/to/FlameGraph/flamegraph.pl out.folded > cpu_flamegraph.svg
Off-CPU 火焰图(等待/阻塞分析)
# 使用 bpftrace(需要 Linux 4.9+)
bpftrace -e 'profile:hz:99 { @[ustack] = count(); }' > out.txt
Java 火焰图(async-profiler)
# async-profiler 是 Java 最好的火焰图工具
./profiler.sh -d 30 -f flamegraph.html <pid>
# 分析堆分配(内存火焰图)
./profiler.sh -e alloc -d 30 -f alloc_flamegraph.html <pid>
如何读火焰图:
- 顶部的宽平台 = CPU 热点函数(优先优化)
- 底部是入口(main/run 等)
- 点击可以展开查看调用详情
综合分析流程
快速诊断脚本(60 秒)
# 参考 Brendan Gregg 的 Linux 60s 检查清单
uptime # 1. 负载趋势
dmesg | tail -20 # 2. 内核错误
vmstat 1 5 # 3. 整体资源(r/b/si/so/in/cs)
mpstat -P ALL 1 5 # 4. CPU 每核使用率
pidstat 1 5 # 5. 进程级 CPU
iostat -xz 1 5 # 6. 磁盘 I/O
free -m # 7. 内存
sar -n DEV 1 5 # 8. 网络接口
sar -n TCP,ETCP 1 5 # 9. TCP 统计(重传率)
top # 10. 总览
常见问题排查
| 现象 | 优先检查 | 工具 |
|---|---|---|
| CPU 使用率高 | us 高 → 代码热点;sy 高 → 系统调用多;wa 高 → I/O 等待 | top/perf/strace |
| 内存持续增长 | 堆内存泄漏 / 直接内存泄漏 | jmap/pmap/valgrind |
| 磁盘 I/O 高 | await 延迟 / %util 利用率 / 哪个进程 | iostat/iotop/lsof |
| 网络延迟高 | TCP 重传 / 连接队列积压 / DNS 解析慢 | ss/tcpdump/netstat -s |
| 响应时间抖动 | GC 停顿 / 上下文切换 / 磁盘 I/O 抖动 | vmstat/pidstat/GC 日志 |
| 进程僵死 | D 状态进程(I/O 等待)/ 死锁 | ps/jstack/strace |
Java 服务性能排查快速流程
# 1. 查看 JVM 线程状态
jstack <pid> | grep -E "BLOCKED|WAITING|TIMED_WAITING" | wc -l
# 2. 查看 GC 情况
jstat -gcutil <pid> 1000 10
# 3. 查看堆内存
jmap -heap <pid>
# 4. 生成堆转储(OOM 分析)
jmap -dump:format=b,file=/tmp/heap.hprof <pid>
# 用 MAT / VisualVM 分析 heap.hprof
# 5. 查看线程 CPU 使用(找 CPU 热点线程)
top -Hp <pid> # 找 CPU 最高的线程 TID
printf "%x\n" <tid> # 转为十六进制
jstack <pid> | grep -A 20 "nid=0x<hex_tid>"
参考资料
- 《Linux 性能优化实战》— 全册(倪朋飞,极客时间)
- Brendan Gregg — Linux Performance Tools(brendangregg.com/linuxperf.html)
- 《性能之巅》— Brendan Gregg(Systems Performance: Enterprise and the Cloud)
评论 (0)
发表评论