2、Linux性能工具集:perf、strace、ltrace、top、htop、vmstat、iostat、netstat、sar 的安装与基本使用

说实话,刚入行那会儿,我面对一台卡成PPT的服务器,第一反应就是重启。后来被前辈骂了一顿,才明白——不会用工具的性能工程师,跟赤手空拳上战场没啥区别。

这一章,我把Linux下最常用的9个性能工具给你捋一遍。每个工具我都踩过坑,有些坑现在想起来还肉疼。你跟着我走一遍,至少能少走半年弯路。

2.1 工具全景:一张图看懂谁该用在哪

先给你画个框架。这9个工具,说白了分三类:

  • 系统级监控:top、htop、vmstat、iostat、sar —— 看整体健康度
  • 进程级追踪:perf、strace、ltrace —— 钻到代码里看细节
  • 网络诊断:netstat —— 查连接、查端口

我习惯把它们比作医院的检查设备:top是体温计,perf是CT机,strace是胃镜。各有各的用处,别拿体温计去查胃病。

核心原则:先宏观,后微观。别一上来就strace,先看看top和vmstat,锁定方向再深挖。

2.2 安装:别让工具成为第一道坎

很多新手卡在安装这一步。其实大部分工具都在系统源里,一行命令搞定。

Debian/Ubuntu 系

# 更新源
sudo apt update

# 一次性安装所有
sudo apt install -y linux-tools-common linux-tools-$(uname -r) \
    strace ltrace htop sysstat net-tools

# 验证安装
perf --version
strace --version
htop --version

RHEL/CentOS 系

# 安装EPEL源(有些工具在EPEL里)
sudo yum install -y epel-release

# 安装工具集
sudo yum install -y perf strace ltrace htop sysstat net-tools

# 注意:CentOS 7 默认的 perf 版本较低,建议用 devtoolset 升级
sudo yum install -y centos-release-scl
sudo yum install -y devtoolset-9-perf
我的经验:在Ubuntu上装perf时,记得装对应内核版本的linux-tools。我见过有人装错版本,跑perf stat直接报"Kernel not supported",折腾了两小时才发现是版本不匹配。

2.3 top & htop:系统体检第一站

top是我每天打开终端第一个敲的命令。它告诉你:CPU谁在吃?内存谁在占?

top 基本操作

# 启动
top

# 常用交互快捷键(按一次就生效)
# 1 - 显示每个CPU核心的负载(默认只显示总负载)
# M - 按内存使用排序
# P - 按CPU使用排序
# k - 杀掉进程(输入PID和信号)
# q - 退出

我记得有一次线上告警,CPU飙到100%。我按1一看,8个核里7个空闲,就一个核跑满了。再按P排序,发现是个单线程的Python脚本在死循环。要是没按1,我可能还在傻傻地看总负载。

htop:top的颜值升级版

# 启动
htop

# 优势
# - 彩色显示,一眼看出CPU/内存/交换分区使用率
# - 支持鼠标操作(点一下就能排序)
# - 树形视图(F5),看清进程父子关系
# - 垂直/水平滚动,不怕进程太多
注意:htop虽然好看,但默认不显示线程。想看线程,按H键切换。我曾经排查一个Java应用,htop里只看到一个进程,用H才发现里面藏了50多个线程在打架。

2.4 vmstat:系统瓶颈的X光机

vmstat是我个人最爱的工具之一。它用一行数据告诉你:系统到底卡在哪。

# 每2秒输出一次,共输出5次
vmstat 2 5

# 输出示例
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0 102400 204800 102400 512000    0    0    10    20  500 1000 30 10 55  5  0

关键字段解读:

字段含义正常值异常信号
r运行队列(等待CPU的进程数)< CPU核数*2> CPU核数*5,说明CPU不够用
b阻塞队列(等待I/O的进程数)接近0持续>0,说明磁盘或网络I/O是瓶颈
si/so交换分区换入/换出0持续非0,说明内存不足
waCPU等待I/O的时间百分比< 10%> 30%,磁盘扛不住了
避坑指南:我曾经遇到一个案例,wa高达60%,但iostat显示磁盘利用率才20%。后来发现是磁盘控制器驱动有问题,导致I/O请求排队但没真正下发。所以,别只看一个指标,要交叉验证。

2.5 iostat:磁盘性能的显微镜

当vmstat告诉你wa偏高时,就该iostat上场了。

# 安装(sysstat包)
sudo apt install sysstat   # Debian/Ubuntu
sudo yum install sysstat   # RHEL/CentOS

# 每2秒输出一次,监控sda磁盘
iostat -x sda 2

# 输出示例
Device:   rrqm/s wrqm/s   r/s   w/s  rkB/s  wkB/s avgrq-sz avgqu-sz await r_await w_await  svctm  %util
sda         0.00   0.00 100.0 200.0 400.0 800.0     8.00     2.00  6.67    5.00    7.50  0.50  15.00

核心指标:

  • %util:磁盘忙绿百分比。超过80%就要警惕,接近100%说明磁盘是瓶颈
  • await:平均I/O等待时间(毫秒)。机械盘一般<10ms,SSD<1ms
  • r_await / w_await:读写分别的等待时间。如果读等待高,可能是缓存命中率低;写等待高,可能是日志刷盘太频繁
我的经验:有一次数据库慢查询,iostat显示%util只有30%,但await高达50ms。仔细一看,r_await是5ms,w_await是95ms。原来是MySQL的binlog刷盘策略设成了每次提交都fsync,把写操作拖死了。改成组提交后,await降到5ms。

2.6 netstat:网络连接的侦探

netstat虽然老,但稳。排查端口冲突、连接数异常、半连接攻击,它都是首选。

# 查看所有监听端口
netstat -tlnp

# 查看所有连接(包括已建立的)
netstat -anp

# 统计各状态连接数
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

# 输出示例
ESTABLISHED 120
TIME_WAIT   350
CLOSE_WAIT  5

状态解读:

  • TIME_WAIT:正常,主动关闭连接的一方会停留2MSL(约2分钟)。但如果超过几万个,说明短连接太多,考虑连接池或长连接
  • CLOSE_WAIT:异常!对方关闭了连接,但你的程序没调用close()。这是代码bug,不修的话连接数会涨到上限
  • SYN_RECV:收到SYN但没完成三次握手。如果数量很大,可能是SYN Flood攻击
我曾经接手过一个Java服务,CLOSE_WAIT飙到8000多,服务直接拒绝新连接。查代码发现是HTTP客户端的响应流没关闭。加了个try-with-resources,问题解决。记住:CLOSE_WAIT是代码问题,不是配置问题。

2.7 sar:历史数据的时光机

问题发生的时候你不在现场?sar可以帮你回放。

# 启动数据采集(sysstat服务)
sudo systemctl start sysstat
sudo systemctl enable sysstat

# 查看今天的CPU使用率历史
sar -u

# 查看今天的内存使用历史
sar -r

# 查看指定时间范围(例如10:00到11:00)
sar -u -s 10:00:00 -e 11:00:00

# 查看昨天的数据(默认保存7天)
sar -u -f /var/log/sysstat/sa$(date -d 'yesterday' +%d)

为什么重要? 很多性能问题是间歇性的。你盯着的时候它不出现,你一走它就崩。sar记录了系统每10分钟的快照,可以帮你找到规律——比如每天下午3点CPU飙升,是不是定时任务在作怪?

我的习惯:每台服务器我都开启sysstat,保留30天数据。有一次排查一个"每周一早上9点数据库变慢"的问题,sar显示那个时间点磁盘写IOPS翻了三倍。顺藤摸瓜,发现是备份脚本在跑。把备份时间挪到凌晨,问题解决。

2.8 perf:CPU性能的终极武器

perf是Linux内核自带的性能剖析工具。它能告诉你:CPU时间到底花在哪一行代码上。

# 统计CPU周期事件(默认)
perf stat ./my_program

# 采样分析(最常用)
perf record -g ./my_program   # -g 记录调用栈
perf report                   # 查看热点函数

# 实时采样正在运行的进程(不重启)
perf top -p PID

实战案例:

# 假设有个程序跑得慢
perf record -g ./slow_program
perf report

# 输出中会显示类似:
# 45.67%  slow_program  [.] compute_hash
# 20.12%  slow_program  [.] memcpy
# 10.34%  libc-2.31.so [.] __memmove_avx_unaligned_erms

# 看到没?45%的时间花在compute_hash上。点进去还能看到是哪一行。
避坑指南:perf record默认采样频率太高,可能影响程序性能。我一般加-F 99(每秒采样99次),既够用又不至于拖慢程序。另外,perf需要root权限才能访问硬件计数器,记得加sudo。

2.9 strace & ltrace:系统调用和库调用的录音笔

strace跟踪系统调用,ltrace跟踪库函数调用。说白了,一个看内核,一个看用户态。

strace 基本用法

# 跟踪一个命令
strace -c ls                    # 统计各系统调用次数和时间
strace -t -T ls                 # -t 显示时间戳,-T 显示耗时
strace -e open,read ls          # 只跟踪open和read调用

# 跟踪正在运行的进程
strace -p PID

# 输出到文件(避免刷屏)
strace -o trace.log ./program

经典场景:程序启动慢?strace一下,看看是不是在反复打开不存在的配置文件。

# 假设程序启动要10秒
strace -c ./slow_start

# 输出可能显示:
# % time     seconds  usecs/call     calls    errors syscall
# ------ ----------- ----------- --------- --------- ----------------
#  80.23    8.023456        8023      1000          0 read
#  10.12    1.012345        1012      1000          0 openat
#   5.34    0.534567         534      1000          0 stat

# 看到没?read调用花了8秒,而且调用了1000次。八成是在读一个很大的文件,或者读文件时阻塞了。

ltrace 基本用法

# 跟踪库函数调用
ltrace ./program

# 只跟踪特定库
ltrace -e 'libc.so*' ./program

# 统计调用次数和耗时
ltrace -c ./program
我曾经用strace抓到一个诡异的bug:一个C程序每隔几分钟就卡住5秒。strace显示卡住时在调用gettimeofday(),但gettimeofday不应该阻塞啊!后来发现是NTP时间同步导致系统时间回跳,gettimeofday内部等待时钟修正。解决方案:禁用NTP的跳跃式同步,改用渐进式调整。

2.10 工具选择速查表

问题现象首选工具辅助工具看什么指标
CPU 100%top/htopperf top哪个进程/线程吃CPU
系统响应慢vmstat 1sar -ur队列、wa、上下文切换
磁盘I/O慢iostat -x 1sar -b%util、await、svctm
网络连接异常netstat -anpss -tlnpCLOSE_WAIT、TIME_WAIT数量
程序启动慢strace -cperf stat系统调用次数和耗时
内存泄漏top -Msar -rRES持续增长
历史性能回溯sar-对比不同时间段的指标
最后说一句:工具是死的,人是活的。别指望一个工具解决所有问题。我见过有人用strace去查网络延迟,用netstat去查磁盘I/O——方向错了,再好的工具也白搭。先想清楚"我要查什么",再选工具。
Linux性能工具集 · 知识体系 性能问题排查入口 CPU 分析 内存分析 磁盘 I/O 网络诊断 进程追踪 top / htop perf vmstat (r列) top (RES) vmstat (si/so) sar -r iostat -x vmstat (b/wa) sar -b netstat ss strace ltrace perf record 先宏观(top/vmstat)→ 再微观(perf/strace)→ 最后定位根因
可可精品资料库