当生产环境"变慢",我用这套 perf + strace 30 分钟定位瓶颈

摘要:top 里 %CPU 只有 30%,接口却从 50ms 飙到 800ms------这种"慢"最折磨人。本文把基础四件套(top/free/iostat/ss)和进阶双剑客(perf / strace)串成一条可复用的排查链路:先定方向,再选工具,读图定位,交叉验证。所有命令均可直接复现。


0. 为什么不能"上来就 top"

很多同学排障的第一反应是 top,然后看着 %CPU 不高就下结论"CPU 没问题"。但"慢"和"CPU 满"根本不是一回事:

  • 延迟可能耗在磁盘 IO 等待(iowait 高,但 CPU 在闲等);
  • 可能耗在被换页的内存压力(free 变 0、开始 swap);
  • 也可能耗在某个卡住的网络 connect / read(时间根本不体现在 CPU 占用里)。

方向判错,后面再怎么调优都是白做。所以第一步永远是定方向,而不是盲调。

1. 总览:排查链路一张图

scss 复制代码
top / htop         → 整机概览,看 load、%wa、si/so
  ↓ 定方向
CPU? / 内存? / IO?
  ↓ 选工具
perf(CPU热点)  strace(syscall阻塞)  iostat(磁盘)  ss(网络)
  ↓ 出图
火焰图 / strace -T 高耗时调用
  ↓ 交叉验证
iostat ↔ pidstat ↔ free/vmstat 互相印证
  ↓ 结论
改代码 / 调参数 / 扩容

工具分工边界:

工具 擅长 看什么
perf CPU 热点、内核态开销(on-CPU) 哪个函数最占 CPU
strace 系统调用级追踪 进程卡在哪个 syscall(IO/锁/信号)
iostat / ss 系统级 IO / 网络 磁盘 %util、连接数分布

2. 基础四件套(先定方向,5 秒出结论)

bash 复制代码
# CPU / 负载
top -b -n 1 | head -20
mpstat 1 3                      # 看每核,重点盯 %iowait

# 内存(看 available,别只看 free)
free -h && vmstat 1 5           # si/so 不为 0 = 内存开始换页

# 磁盘
iostat -x 1 5                   # %util>70% 忙,await>10ms 慢

# 网络
ss -s                          # 连接数统计
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn   # 状态分布

判定口诀:

  • load / CPU核数 > 0.7 才健康;
  • free -h 看 available,不是 free------Linux 会用空闲内存做 cache;
  • vmstat 的 si/so > 0 或 %wa > 20%,基本能锁定内存/磁盘方向。

3. CPU 瓶颈:perf 抓热点

bash 复制代码
# 安装(版本最好与内核一致)
apt install -y linux-tools-common linux-tools-$(uname -r) strace

# 系统范围采样 30s,99Hz 是社区惯例(避开整百共振)
perf record -F 99 -ag -- sleep 30

# 只看某个进程
perf record -F 99 -p $PID -g -- sleep 30

# 交互式看热点
perf report
perf top -p $PID

踩坑:-F 别用 999,-F 99 足够,过高会放大自身开销、污染结果。

4. 内存瓶颈:别只看 free

bash 复制代码
# 量化缓存与缺页(major-faults 偏高 = 已逼出磁盘换入)
perf stat -e cache-misses,cache-references,page-faults,major-faults \
  -p $PID -- sleep 10

# 定位是谁在触发缺页
perf record -e page-faults -ag -p $PID -- sleep 10

# 系统级印证
free -h && vmstat 1 5
cat /proc/meminfo

major-faults 显著偏高往往意味着内存压力已经逼出 IO;cache-misses 高说明热点数据没留在 CPU 缓存。深度泄漏分析还需 jemalloc/jeprof、Valgrind 等,本文不展开。

5. IO 瓶颈:strace 看"卡在哪个调用"

bash 复制代码
# 只看文件/网络调用的耗时(定位阻塞点)
strace -Ttt -e trace=file,network -f -p $PID

# 汇总统计更快
strace -c -f -p $PID -- sleep 5

# 系统级印证
iostat -x 1 && pidstat -d 1

-T 标出的高耗时 read/write/connect 就是阻塞点。比如某 connect 每次几百毫秒,问题大概率在网络或下游服务,而不是本机 CPU。

6. 综合实战:接口变慢决策树

bash 复制代码
# 1) 定方向
top -b -n 1 | head -20 && mpstat 1 3

# 2) CPU 热点
perf record -F 99 -ag -p $PID -- sleep 20

# 3) syscall 层
strace -Ttt -e trace=file,network -f -p $PID -- sleep 5

# 4) 内存 / 缓存
perf stat -e cache-misses,page-faults -p $PID -- sleep 10
free -h && vmstat 1 5

典型结论:

  • perf 显示某函数占 CPU 最高 → 改代码优化;
  • strace 显示 connect 高耗时 → 排查下游/网络;
  • vmstat 的 si/so 不为 0 → 加内存或查泄漏。

7. 避坑清单(生产环境必看)

  • strace 通过 ptrace 显著拖慢目标进程 :生产慎用、避免长时间 attach;统计优先用 -c,拿完数据立刻退出。
  • perf 频率并非越高越好 :-F 99 是惯例。
  • 权限约束 :cat /proc/sys/kernel/perf_event_paranoid 取值越高限制越严(常见默认 2~4),内核态/整机数据需要 CAP_PERFMON / CAP_SYS_ADMIN;容器内需放开 securityContext。
  • 采样要覆盖真实业务高峰,别把偶发抖动当稳定根因。

8. 一页速查表

方向 工具 关键命令 判读
CPU perf perf record -F 99 -ag / perf top 热点函数占用
内存 free/vmstat free -h / vmstat 1 available<10%、si/so>0
内存 perf perf stat -e page-faults major-faults 高
磁盘 iostat iostat -x 1 %util>70%、await>10ms
网络 ss ss -ant TIME-WAIT/CLOSE-WAIT 过多
syscall strace strace -Ttt -e trace=file,network -p 高耗时 read/write/connect

结论 :排查"慢"的核心不是工具多熟,而是先定方向、再选工具、读图定位、交叉验证这条链路走稳。把这套命令和决策树收进你的排查剧本,下次告警来了就能少绕弯路。


相关推荐
未来之窗软件服务9 小时前
Linux 运维日志删除的多种方式—东方仙盟
linux·运维·服务器·仙盟创梦ide·东方仙盟
卓豪终端管理9 小时前
IT 运维视角下的终端数据安全:能力框架与落地清单
运维
小雉系统9 小时前
BcoreOS实战:用一个升级包,让Rocky Linux跑进Debian服务器
linux·运维·服务器·debian
thethefighter9 小时前
快速预览Word、WPS秒开,支持空格弹窗
linux·word·wps·快速预览·空格弹窗·nhdeepview
甜到心里的蛋糕10 小时前
从 QQ 机器人到 B 站 AI 运营:一套可复现的视频流水线踩坑实录
运维·人工智能·python·自动化·视频制作
QYR-分析10 小时前
26.2% 高增!场内及园区无人物流车,厂内短驳自动化的 L4 货运载体
运维·自动化
用户83514140494910 小时前
把日志和寄存器值喂给AI做故障定位,我的实际问法
linux·ubuntu
java_logo10 小时前
Docker 部署 DPanel:轻松搭建轻量容器管理平台
运维·docker·容器·podman·容器管理·dpanel·轩辕镜像
时间售卖铺10 小时前
Oracle DQL精髓:从基础到高级实战
运维·数据库·云原生·oracle
分布式存储与RustFS10 小时前
CI 老被 Docker Hub 的 429 卡住,自建 Registry 把镜像搬进内网
运维·docker·开源·镜像仓库·对象存储·ci·rustfs