资讯动态

Linux性能分析工具实战:从top到perf的排查指南

发布时间:2026/10/15 4:27:28 来源:尧图企业网站定制
刚接手一套出问题的系统时最怕的不是报错而是机器看起来一切正常CPU没爆、内存没满、服务也活着但接口就是慢得像蜗牛。我第一次遇到这种情况一个人在工位前盯着top的输出看了半天愣是没看出门道。后来才明白Linux 性能分析从来不是靠一个工具通吃天下而是需要一套组合拳——Linux常用性能分析工具就是这套组合拳的弹药库。这篇文章写给所有被线上问题折磨过的运维、开发和架构师。我不会罗列一堆命令的手册页而是结合真实排查场景把这套工具按“看什么、怎么用、坑在哪”的思路拆开揉碎。内容覆盖 CPU、内存、磁盘、网络四大核心维度以及从top到perf的完整工具链。无论你是刚入门的新人还是已经踩过不少坑的老手这些基于实测的经验应该能帮你少走弯路。1. 性能排查的整体思路工具是弹药方法论才是武器很多人学性能分析上来就背命令top怎么按、free怎么读、iostat参数一大堆背得滚瓜烂熟真到了线上却依然抓瞎。原因很简单工具只是让你看到数据真正决定你能不能快速定位问题的是你脑子里有没有一条清晰的排查链路。1.1 为什么不能只看某一个指标机器的性能瓶颈往往是“伪装的”。CPU 飙高不一定是代码算力不够有可能是内存不足导致频繁换页磁盘 I/O 升高不一定是真有大量读写有可能是日志文件过大、swap抖动、或者某进程疯狂写临时文件。单一指标就像盲人摸象摸到腿就说是一根柱子误判概率极高。我见过一个典型案例某服务深夜告警top显示 CPU user 占用接近 100%开发第一反应是代码死循环结果检查半天发现是磁盘写入延迟过高导致日志缓冲线程阻塞最终把 CPU 资源耗尽。所以排查的第一步永远是多维数据同时看而不是盯住一个数字。1.2 建立自己的排查坐标系我的习惯是给性能问题分三层资源层CPU、内存、磁盘、网络的基础使用率这是最先要看的地表数据。内核层上下文切换、中断、运行队列长度、锁竞争这些能反映资源是否被低效利用。应用层进程的调用栈、热点函数、锁等待、GC 停顿最终落到代码层面才知道根因。这三层不是顺序执行而是互相验证。比如资源层看到 CPU 升高直接跳去查应用层热点函数如果查不到因为热点在内核态就得回到内核层看上下文切换。1.3 常用的应急三板斧真到了线上告警没时间优雅地做全量分析我的做法是先跑top和uptime看 load average 和 CPU 分布5 秒钟建立整体认知。再用vmstat 1连续采样几次看 CPU idle、waittio、si/so 是否异常。最后按需上pidstat、iostat或perf缩小范围到具体进程和函数。这套三板斧并非什么高深套路但它保证你无论遇到什么诡异问题都有最基本的着手点不会因为信息过载而卡在原地。提示任何性能分析工具的输出都是瞬时快照。线上问题往往是间歇性的单次快照可能什么都看不到。正确的做法是连续采样并保留日志建议vmstat 1 10每秒一次共10次这类操作至少做三轮。2. 常用核心工具逐个拆解从安装到实战的避坑指南2.1top、htop系统总览的第一眼top是所有人接触的第一个工具但绝大多数人只用了它 10% 的能力。默认界面里除了看 %CPU 和 %MEM 两列我建议你养成习惯关注这几个字段load average1/5/15分钟注意区分它和 CPU 使用率的关系。单核机器 load 超过 1 就说明有任务在排队多核机器则要看 load/核数 的比值。us、sy、ni、id、wa、hi、sius高是用户态程序问题sy高则要小心内核态消耗系统调用过多、锁竞争wa高说明磁盘跟不上si软中断高往往和网络吞吐量过大有关。僵尸进程数量如果top里看到多个Z状态的进程别忽略它们通常说明父进程没有正确回收子进程长时间累积会耗尽 PID 资源。htop是top的增强版支持彩色显示和鼠标操作按F5可以切换到树形视图能很直观地看到父子进程关系。但请注意htop在部分精简系统上默认没装需要yum install htop或apt install htop。实操心得top默认按 CPU 排序但排查内存问题时建议按ShiftM切到内存排序。另外top -p 12345可以只监控指定 PID这在定位某个进程的波动时很实用。2.2vmstat系统整体健康度的扫描仪vmstat是我个人最喜欢的工具因为它用一行输出就把系统核心指标全暴露出来了。命令格式是vmstat [间隔秒数] [采样次数]比如vmstat 1 5表示每秒采样一次共5次。输出里重点看四列列名含义判读标准r运行队列长度持续大于 CPU 核数说明有任务在排队waCPU 等待 I/O 的时间占比持续超过 30% 需要警惕磁盘能力si、soswap 换入换出量持续非 0说明物理内存不够了cs上下文切换次数数值猛增通常和线程过多或锁竞争相关常见误区很多人只看free命令判断内存忽略了vmstat里的si/so。实际上当内存压力大的时候系统会先把不活跃页面换到 swap这个过程的性能损耗远大于直接分配内存。我排查过一个 Java 服务free显示还有 8GB 可用但服务周期性卡顿最后发现是 swap 分区频繁读写导致的。2.3mpstat与pidstat从系统级别到进程级别当top告诉你 CPU 整体飙高但你看不出是哪个 CPU 核有问题时就该用mpstat -P ALL 1了。它会打印每个 CPU 核的使用情况。多核系统里某个核跑到 100%、其他核空闲往往说明存在锁竞争或者中断绑核不均的问题。pidstat则更进一步直接定位到具体进程。我最常用的几个参数pidstat -u 1看进程 CPU 使用率pidstat -r 1看进程内存使用pidstat -d 1看进程磁盘 I/Opidstat -w 1看进程上下文切换次数避坑提示pidstat默认只显示非零值所以当你觉得“怎么什么都没输出”的时候不妨先看看是不是这个原因。另外排查线程问题时要用-t参数它会显示进程里的具体线程。2.4free内存问题的表面与实质free -h输出里有个最容易误读的地方。很多人看到free那列数值很小就以为内存不足但其实 Linux 的内存管理策略是“能用就用”大量的内存被用作缓存buff/cache这部分在进程需要时是可以释放的。真正的内存问题要看available列它估算的是“在不触发 swap 的情况下还能分配多少内存”。当available持续走低、free接近 0同时vmstat里的si开始有数值这才是内存告急的信号。实操心得排查内存泄露时单纯靠free是不够的必须配合pidstat -r或者监控进程的 RSS 变化趋势。我习惯每 5 秒记录一次某进程的内存值持续半小时如果曲线一路向上不回落基本可以判定有内存增长异常下一步就该用jmapJava或valgrindC/C定位具体对象了。2.5iostat与iotop磁盘到底忙不忙磁盘性能问题有个特点表面上看 IO 利用率不高但实际响应时间已经恶化。iostat -x 1是查看磁盘细节的正确姿势重点看这几个字段%util磁盘忙闲程度但注意接近 100% 不代表已经到极限还要结合avgqu-sz平均队列长度判断是否真的有任务在排队。r_await、w_await读写请求的平均响应时间毫秒。SSD 正常时通常是个位数如果飙到几十甚至上百说明磁盘能力不够或者有异常竞争。svctm这个字段在 SCSI 设备上有误导性很多老教程还在推荐看它实际上现在主流内核版本已经不建议参考。iotop则是看“哪个进程在读写磁盘”的利器作用和pidstat -d有点重叠但输出更直观。使用iotop -o只显示正在做 I/O 的进程避免刷屏。常见问题磁盘%util不高但应用写日志总超时。这种情况多半是磁盘存在瞬时抖动或者文件系统元数据操作过于频繁。用iostat -x 1 10连续采样抓瞬时峰值不要只看平均值。2.6sar历史数据的时光机sar是 sysstat 包里的老牌工具它的价值在于持续采集。我习惯在服务器上配置cron每 10 分钟执行一次sar -o收集数据这样系统出问题时可以回溯到几小时甚至几天前的指标而不是事后猜测。常用命令sar -u查看 CPU 历史数据sar -r内存历史数据sar -b磁盘 IO 历史数据sar -n DEV 1 3查看网络接口流量避坑提示sar默认可能只保留 7 天的数据保存位置在/var/log/sa/。如果你的磁盘空间紧张建议适当调整保留策略。另外新装的系统别忘了启动 sysstat 服务否则不会自动采集。2.7perf与strace深入代码内部的显微镜前面说的工具都是从系统资源维度观察但很多问题最终要落到“代码为什么这么慢”上。这时perf和strace就该出场了。perf top可以实时查看系统内的热点函数它的原理是基于内核的 PMU 硬件计数器采样性能开销比strace小得多。定位 CPU 热点时我一般先跑perf top -p PID看到明显的热点函数后用perf record -g -p PID sleep 30录制调用栈再用perf report生成火焰图数据。strace则是追踪系统调用的利器。它能看到进程在用户态和内核态之间所有的交接动作比如文件打开失败、网络连接超时、资源锁等待等。使用命令strace -f -p PID -o /tmp/trace.log-f表示同时跟踪子线程-o输出到文件避免刷屏。注意strace对性能影响极大线上生产环境慎用。如果非要用建议加-c参数做系统调用汇总统计而不是全量记录每个调用的参数细节。2.8 网络排查四兄弟netstat、ss、iftop、ping网络问题单独拿出来说因为它经常被忽略。很多时候 CPU 不高、内存不低、磁盘也正常但服务就是卡顿问题很可能在网络层。netstat和ss查看端口监听、连接状态的标配。重点看TIME_WAIT、CLOSE_WAIT两个状态。CLOSE_WAIT堆满表示应用没有正确关闭连接这是最常见的网络 bugTIME_WAIT过大通常和短连接过多有关。ss -s快速查看当前连接状态的汇总比netstat更高效。iftop实时查看网络接口流量看哪个 IP 在和你通信、带宽占用多少。ping和mtr排查延迟和丢包mtr结合了traceroute和ping能看到每一跳的丢包率。实操心得排查网络性能问题要区分延迟是本地还是远端造成的。ping本机网关延迟高说明本地网卡或物理链路有问题ping远端延迟高则要逐跳分析不能一刀切归咎于某一段。3. 一次真实排查实录从 CPU 飙高到定位根因理论说再多不如带大家走一遍实际的排查流程。有一次我们的某服务突然告警现象是接口响应时间从平均 50ms 涨到 3 秒。我接手时的初始信息只有“服务变慢”没有任何报错日志。3.1 第一轮采样建立整体认知我先执行了uptime和top$ uptime 14:23:11 up 30 days, 2:31, 1 user, load average: 12.56, 8.32, 5.10load average 1 分钟 12.56说明系统压力在快速上升。top里看到多个 Java 进程 CPU 占用偏高同时wa列达到 18%有 I/O 等待。按照前面的思路这不是单纯的 CPU 问题磁盘也在拖后腿。3.2 第二层区分 CPU 与磁盘的因果我同时开了两个终端一个跑vmstat 1 10一个跑iostat -x 1 10。$ vmstat 1 10 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 8 1 20480 1024000 12000 600000 0 0 12 512 45 18000 35 20 25 18 2r运行队列为 8高于核数4核说明 CPU 确实有压力但更扎眼的是wa18% 和b不可中断睡眠进程为 1表示有进程卡在 I/O 等待上。iostat输出显示/dev/sda的w_await从 5ms 飙到 45ms磁盘响应明显恶化。3.3 第三层追查具体进程与热点函数我使用pidstat -d 1找到了磁盘读写最频繁的进程 PID 1024是一个日志收集 agent。同时用pidstat -w 1看上下文切换发现这个进程的cswch/s自愿上下文切换特别高说明它在频繁进行 I/O 操作。顺着这个线索用strace -c -p 1024做了 10 秒统计发现write系统调用次数异常多而且每次都往同一个文件描述符写入大量数据。进一步排查发现这个 agent 的日志文件没有配置轮转已经膨胀到 80GB而且应用的日志级别被误调为 DEBUG导致每秒几万条日志写入。3.4 故障总结根因链是这样的日志级别误配 → 大量 write 调用 → 磁盘响应变慢 → Java 服务在写日志时被阻塞 → 接口线程池耗尽 → 整体响应变慢。CPU 的升高其实是 JVM 在处理日志字符串拼接和 IO 阻塞重试时带来的间接结果并非真正热点。修复方式日志级别改回 INFO、配置 logrotate 轮转、给日志文件所在磁盘扩容。改动上线后vmstat的wa回落到 2% 以下接口响应恢复正常。这个案例想说明的是性能分析工具的输出永远是链路上的一个片段你必须把它们串联起来看才不会被表面的 CPU 假象带偏。4. 高阶技巧与常见问题速查让你少踩几个坑4.1 如何应对“工具没装”生产环境出于精简考虑很多工具默认未安装。systat 包里的mpstat、iostat、sar在 CentOS/RHEL 上需要yum install sysstatpidstat通常包含在sysstat里iftop、htop、iotop属于第三方源需要 EPEL 或编译安装。避坑提示不要在排查现场花大量时间编译安装工具。建议提前在镜像/初始化脚本里把常用工具全部装好顺手写入监控采集配置。遇到完全没法安装的场景可以考虑用/proc虚拟文件系统顶上——比如直接cat /proc/loadavg看负载cat /proc/meminfo看内存。虽然麻烦一点但关键时候能救命。4.2 数值到底该怎么解读这是新手最容易犯迷糊的地方。我见过有人看到%CPU超过 100% 就以为是 Bug其实那是多核累计值4 核进程满载显示 400% 才是正常的。load average也不是越低越好对多核系统来说load 等于核数说明满载但没排队超过核数才是压力过载。另一个常见误读是磁盘%util。有些老教程说%util接近 100% 就是磁盘瓶颈这个说法不完全对——%util只表示设备忙的时间比例并不能直接反映有没有请求在排队。结合avgqu-sz一起看才靠谱。4.3 现场排查的几条军规永远先看 load average 和 wa。这两个指标能快速区分 CPU 密集型、IO 密集型、还是内存不足。采样要连续不要只看一次。性能问题基本都是波动的单次快照没有意义。至少连续采样 10 次以上再下结论。保留现场。发现问题后先别急着重启服务。先收集top -b -n 1、vmstat 1 10、free -h、ss -s这些命令的输出存到文件里然后再做操作。记录变更。很多时候问题不是突然出现的而是最近一次发布或配置变更导致的。排查前先问自己过去一小时内我们改过什么4.4 常见问题速查表现象优先查看项可能根因CPU user 高、sys 低perf top、pidstat -u代码热点、死循环、GC 频繁CPU sys 高、user 低vmstat的cs、strace -c系统调用过多、锁竞争wa持续 30%iostat -x、iotop -o磁盘能力不足、日志刷太狠si/so非零free、pidstat -r物理内存不足换页严重网络延迟高、CPU不高ss -s、iftop、ping逐跳连接数堆积、链路丢包、防火墙僵尸进程累积ps -ef | grep defunct父进程未回收子进程代码缺陷多核使用不均mpstat -P ALL 1中断绑核、锁竞争、线程数设置不合理4.5 关于工具链的扩展建议除了上面聊到的还有一套组合值得深入bpftrace和bcc工具集如filetop、biosnoop、tcplife。它们基于 eBPF 技术可以在内核态动态追踪几乎不产生额外性能开销。比如你想知道“是哪个进程在写哪个文件拖慢了磁盘”filetop一行输出就能告诉你而传统手段要折腾大半天。虽然学习曲线略陡但强烈建议性能排查经验丰富的同学投资时间研究一下。如果说普通工具是手电筒eBPF 就是探照灯——它能照进内核的最深处看到系统调用的流量全貌。但它的前提是内核版本支持4.4且有 root 权限容器环境里使用限制较多。先把手头的经典工具用熟练再考虑追新是我给你的实在建议。5. 写在最后的个人经验这套工具链我已经用了很多年从最初的只会在top里看 %CPU到现在能 10 分钟内定位深藏在调用链里的瓶颈最大的体会是别指望某一个工具直接告诉你答案。工具负责给你客观数据负责推理的是你的大脑。每次排查完我都会把当时的采样输出和根因分析存进一个本地笔记时间久了就成了自己的知识库——这里面的模式识别能力比任何工具书都值钱。最后分享一个小技巧给常用的命令组合起一个别名比如alias perf5pidstat -w 1; vmstat 1 5; iostat -x 1 5线上告警时手一抖敲错命令是常有的事预先把套路固化下来能省下不少关键时刻的心智消耗。工具就放在那里谁都能敲两下但能不能在最短时间里从数据里读出真相才是运维和开发之间真正的分水岭。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑