生产环境突然变慢这事搁谁身上都慌。尤其是那种线上正在跑业务、老板站在你身后盯着屏幕、客服群里已经开始刷“系统卡顿”的时候手里没两把趁手的排查工具根本撑不住场面。我这几年处理过不少类似的线上事故最后沉淀下来一套比较固定的组合拳先用 perf 看 CPU 到底烧在哪个函数里再用 strace 看进程卡在哪个系统调用上绝大多数性能瓶颈30 分钟内基本都能锁定方向。这篇文章就把我实际排查的思路、命令、判断方法完整记录下来。不是教科书式的工具手册而是我踩过坑之后总结的一套实战打法。不管你是后端开发、运维还是 SRE遇到“服务变慢但不知道从哪里下手”的场景这套方法都能帮你快速缩小范围。1. 排查前的黄金三分钟先确认现象再动手抓数据很多人在生产环境一出问题就急着敲命令结果抓了一堆没用的数据反而耽误时间。我自己的习惯是先花三分钟搞清楚三个问题慢是整体的还是局部的是突然变慢还是逐渐变慢用户体感的“慢”在监控上对应什么指标1.1 整体变慢还是局部变慢决定排查方向“生产环境变慢”这个描述太模糊了。是所有的接口都慢还是只有某个接口慢是所有节点都慢还是只有某台机器慢是整个应用变慢还是数据库、Redis、Nginx 这些依赖组件变慢如果只有某个接口慢大概率是代码逻辑问题比如死循环、锁竞争、数据库慢查询。如果是所有接口都慢可能是机器资源耗尽比如 CPU 跑满、内存不够触发频繁 GC、磁盘 IO 阻塞。如果是单台机器慢而其他机器正常大概率是负载不均或者这台机器本身有问题可能磁盘坏了、网卡降速了、邻居虚拟机在抢资源。我常用的快速判断命令就几条uptime看负载free -h看内存top看 CPU 和内存占用排序iostat -x 1看磁盘 IO。先看 load average 高不高再看是 user 占用高还是 sys 占用高如果是 user 高说明是业务代码在烧 CPU如果是 sys 高说明进程在内核态频繁折腾比如系统调用太多、上下文切换频繁、IO 操作密集。1.2 监控曲线会说话别急着上工具如果公司有监控系统先拉一下关键指标的趋势图。特别关注三个时间点变慢开始的节点、高峰期、以及最近一次发版时间。很多时候“突然变慢”其实是上一次发布埋的雷回滚一下就好了根本不用抓 perf。监控重点看四类指标CPU 使用率、平均负载、RT响应时间、错误率。如果 CPU 使用率从 20% 突然飙到 90% 以上那 perf 就是首选工具。如果 CPU 不高但接口 RT 很高那问题可能在锁等待、网络延迟或者外部依赖上strace 更合适。如果错误率也在涨得先看是不是有异常流量打进来或者依赖的下游服务挂了。这里有一个我反复踩过的坑不要一上来就直接 perf 或 strace。生产环境的进程 strace 附加上去会有短暂的停顿尤其是高并发进程attach 的瞬间会导致请求超时。如果情况不是特别紧急先把现场信息收集齐了再上工具。如果情况非常紧急也要做好心理准备strace 附加生产进程本身就是一次“微创伤”操作。2. perf 定位 CPU 热点看看 CPU 到底在忙什么perf 是 Linux 内核自带的性能剖析工具它利用硬件性能计数器可以精确告诉你 CPU 时间片都消耗在哪些函数上。当遇到 CPU 飙高、load average 异常的场景perf 是我的首选举证工具。2.1 perf top 快速看一眼perf record 记录证据链如果情况紧急我通常会先跑一条perf top -p PID -g直接看那个进程当前实时的函数调用热点。加上-g参数会显示调用链能快速定位问题函数是被谁调起来的。这条命令建议在问题发生时抓 10 到 30 秒足够看出主函数热点分布了。如果问题能稳定复现或者你想拿一份完整的证据给团队看用perf record采样一段时间再分析。基本命令是perf record -F 99 -p PID -g -- sleep 30 perf report -g graph-F 99表示每秒采样 99 次这个频率是 Brendan Gregg 的经典推荐值既可以采集到足够的样本又不会因为频率太高给系统带来额外负担。-g记录调用栈sleep 30表示采样 30 秒。跑完perf report就能看到按 CPU 占用率排序的函数列表按回车展开调用链。这里有个关键点perf record需要 root 权限或者配置好 perf_event_paranoid 内核参数。很多生产环境默认不允许普通用户跑 perf如果提示Permission denied要么用 root 执行要么临时调整一下权限。我一般不推荐为了跑一次 perf 去改内核参数直接找运维要个 root 权限或者用 sudo 就行。2.2 读 perf report 的三种典型形态对应三类问题perf report 出来的结果看多了就会发现基本都是那几种套路我分享三个最常见的情况。第一种热点集中在某个业务函数上占比一家独大超过 60%。这种基本就是代码逻辑问题常见原因有正则表达式灾难性回溯、JSON 序列化大对象、字符串频繁拼接、死循环等。我处理过一个真实案例一个日志解析服务 CPU 100%perf 显示热点集中在java.util.regex.Pattern$GroupCurly这个方法上最后定位到一条正则表达式出现了灾难性回溯一个字符一个字符地回溯CPU 直接被烧没了。解决办法很简单换掉那行正则实现CPU 直接降到 5%。第二种热点集中在锁相关的内核函数上比如futex_wait、queued_spin_lock_slowpath伴随大量线程上下文切换。这种是锁竞争多个线程在抢同一把锁。perf 看到的是 CPU 大量消耗在锁的等待和切换上而不是在真正干业务。第三种热点集中在copy_user_enhanced_fast_string、clear_page_erms这类内存拷贝和清零函数上。这种通常是程序在频繁做大量内存数据拷贝比如大数组复制、大对象频繁创建销毁。除了优化代码逻辑另一个方向是看看是不是 JVM 或者运行时参数没调好GC 太频繁导致内存搬运开销过大。2.3 火焰图给同事看、给领导看的最佳呈现方式perf record 采集的数据直接跑perf report是命令行交互界面说实话不太直观。我习惯在拿到采样数据后生成火焰图一眼就能看出 CPU 的“地形图”——哪块山最高最宽问题就在哪里。生成火焰图要用到 Brendan Gregg 的 FlameGraph 脚本perf script out.perf git clone https://github.com/brendangregg/FlameGraph.git ./FlameGraph/stackcollapse-perf.pl out.perf out.folded ./FlameGraph/flamegraph.pl out.folded cpu.svg把生成的 SVG 文件用浏览器打开悬停可以看到每个色块对应的函数名和占比。火焰图的 X 轴是采样次数占比Y 轴是调用栈深度一个函数如果呈现“平顶山”形状几乎可以断定就是它在烧 CPU。每次排查完我习惯把火焰图截图发到团队群里比写一百字文字描述都管用。3. strace 追踪系统调用当进程卡住看它等什么perf 解决的是“CPU 在忙什么”的问题但生产环境还有一种典型的慢——CPU 不忙load average 也不高可请求就是迟迟不返回。这种情况大概率是进程阻塞在某个系统调用上比如读文件卡在磁盘 IO、网络请求卡在等待对端响应、锁等待卡在 futex 上。strace 就是干这个的。3.1 strace 最常用的三种姿势strace 最基本的使用方式是跟踪进程的系统调用可以直接启动一个新进程也可以附加到已有进程# 方式一启动新进程并跟踪适合测试环境复现 strace -f -tt -T -o /tmp/xxx.log command # 方式二附加到运行中的进程生产环境慎用 strace -f -tt -T -p PID # 方式三只跟踪特定的系统调用 strace -e tracenetwork -p PID参数说明-f跟着子进程一起跟踪-tt打印带微秒级精度的时间戳-T显示每个系统调用消耗的时间-o输出到文件方便分析。-e tracenetwork可以只跟踪网络相关的系统调用减少干扰。一条一条看输出太费眼我通常直接统计耗时 Top 10 的系统调用strace -f -tt -T -p PID -o /tmp/strace.log sleep 30 kill %1 awk {print $NF, $0} /tmp/strace.log | sort -rn | head -20这样能快速筛选出哪些系统调用耗时最长往往是瓶颈所在。3.2 strace 输出怎么看五种高频阻塞点strace 的输出每一行就是一个系统调用事件核心信息包括调用名、参数、返回值、耗时。结合我自己排查过的案例总结出五种典型的高频阻塞点。等待网络连接connect或accept长时间不返回通常是对方服务没响应或者网络不通。通常 connect 阻塞超过几百毫秒就不太正常了配合 ss 或 netstat 可以确认连接状态。等待网络数据现象是read、recvfrom、poll、select、epoll_wait长时间阻塞。如果大量时间花在epoll_wait上侧面说明进程在等事件这本身不是问题但是如果业务导致事件没来那就要排查下游服务了。等待磁盘 IOpread、pwrite、fsync、fdatasync耗时高说明磁盘响应慢可能是磁盘快满了、RAID 在重建、磁盘硬件故障。fsync耗时高还有一个常见诱因是日志没走异步刷盘每次请求都同步刷盘性能肯定好不了。等待锁futex调用返回EAGAIN或者长时间不返回说明线程在等锁。这个场景下 strace 能看到大量的 futex 调用配合 perf 可以确认锁竞争的激烈程度。可疑的文件路径如果 strace 日志里频繁出现某个冷门文件路径的open、read、stat可能是程序在反复读取某个配置文件或者检查某个文件是否存在这本身可能是一个代码层面可以优化的点。3.3 附加生产进程要小心的两个风险第一strace 会让目标进程显著变慢因为它拦截了每一次系统调用相当于给进程装了一个“监控探针”。高并发进程被 strace 附加后请求延迟可能翻好几倍甚至出现超时雪崩。所以 strace 一个生产高并发进程时间越短越好我一般抓 10 到 15 秒就够了拿到关键证据就立刻 detach用 CtrlC 退出。第二strace 默认会跟踪所有子线程和子进程的系统调用输出量可以大到瞬间写满磁盘。一定要加-o指定输出文件并且时刻观察输出文件大小。我有一个习惯strace 加-e trace精确限定要跟踪的系统调用类别比如只看网络相关就用-e tracenetwork只看文件 IO 就用-e tracefile,desc这样信息量小且聚焦定位效率反而更高。4. 一次真实的 30 分钟排查从用户反馈到根因确认理论说再多不如完整走一遍实战流程。下面这个案例是我最近处理的生产事故整个过程非常有代表性。4.1 事故现场支付回调接口 RT 从 50ms 涨到 5s周一早上 10 点多客服群开始反馈用户支付成功后页面回调迟迟不跳转。我赶紧看了一眼监控支付回调接口 P95 延迟从平时的 50ms 涨到了 5 秒但是支付服务和数据库服务器的 CPU 都只有 30% 左右内存也充足。这就很有意思了。CPU 不高说明进程不是被计算卡住的内存充足排除频繁 GC 的可能但 RT 暴增 100 倍说明要么进程在等什么要么依赖服务出问题。我第一步先确认了接口依赖的外部组件状态——Redis、数据库、MQ 都没告警响应都正常。那问题大概率出在应用进程自身。我先用top -H -p PID看了一下这个进程的所有线程确认没有哪个线程 CPU 跑满。接着我用jstack看了下 Java 线程栈这是 Java 服务的额外福利发现大量线程阻塞在 HTTP 调用第三方回调接口的位置。4.2 perf 和 strace 各来一发互相印证锁定根因当时判断阻塞在 HTTP 调用上但我需要更硬的证据。先用 perf 采样看了看 CPU 热点perf top -p PID -g显示热点不在任何业务方法上而是集中在epoll_wait、futex这些内核函数上。这说明进程的大部分线程在等待事件没有在干活和“CPU 不高但 RT 高”的现象吻合。接下来上 strace附加到进程抓了 15 秒。输出文件里futex和poll是两个高频出现的关键词。我重点看了poll相关的行发现大量 poll 超时时间很长等待的 fd 都是 socket。再用ss -tnp确认了这些 fd 对应的 TCP 连接状态发现大量连接处于SYN_SENT状态——也就是说应用发的 HTTP 请求包发出去了但对方一直没回 ACK。到这里根因已经很清楚了应用需要回调的第三方接口所在的服务端网络超时导致大量 HTTP 请求在建立连接阶段就卡住了。深入看发现第三方服务整体不可用其出口防火墙丢包严重TCP 握手永远无法完成客户端的默认超时时间又特别长大量线程就被挂在这里。4.3 复盘沉淀这次事故带来了三个改造点事故恢复后我做了一个简单复盘其实问题不只是第三方故障我们应用本身的健壮性也有三个明显的缺陷。第一HTTP 调用第三方接口的超时时间没有统一配置。当时使用的一个 HTTP 客户端默认连接超时竟然是 10 秒这在生产环境简直不可接受。如果对方服务不可用我们所有调它的请求都会挂 10 秒很容易拖垮我们自己的线程池。改造方案是统一配置连接超时 2 秒、读取超时 5 秒并加上合理的重试策略。第二HTTP 连接池大小设置不合理。因为连接建立卡住连接池被占满后新请求只能排队等RT 进一步恶化。改造后连接池增加了最大连接数并增加了对连接池耗尽快速失败的保护。第三缺少对第三方接口调用的熔断机制。如果连续一段时间内对某个下游的调用失败率达到阈值就应该开启熔断直接快速失败而不是继续拿资源去等一个必失败的结果。这既保护自己也在保护下游不至于在它已经故障的时候继续用流量冲击它。5. 工具之外的判断力什么场景该用 perf什么场景该用 strace工具只是弓箭关键是知道什么时候该射哪支。很多人遇到服务变慢第一个念头就是“我要用 perf 看看”但其实 perf 和 strace 有非常明确的分工用对场景效率翻倍用错场景等于白折腾。5.1 perf 适合“CPU 忙不过来”的场景strace 适合“进程卡着不动”的场景我给自己总结了非常简单的判断口诀CPU 高找 perfCPU 不高找 straceCPU 高但 strace 也看到大量系统调用优先查系统层面。具体来说如果 top 显示进程 CPU 使用率超过 80%且 user 占比高这是 perf 的射程它能看到代码行级别热点。如果 CPU 使用率很低但请求 RT 很高这是“进程在等待”直接用 strace 看它卡在哪个系统调用上。如果 CPU 使用率中高且 sys 占比很高说明进程在内核态忙大量时间耗在系统调用上此时 strace 能看到具体是哪个系统调用perf 能看到调用频次先 perf 还是先 strace 都可以但我一般先 perf 看内核函数热点。这里要特别提醒一点不要把 perf 或者 strace 当成唯一依据。perf 看见 epoll_wait 占比高就断定“进程空闲”这本身没有意义epoll_wait 占比高说明程序的 IO 模型就是事件驱动的大多数时间本来就应该在等待。关键要看业务延迟是否异常以及事件到来后的处理时间是否正常。我好几次差点被这种“伪热点”带偏后来养成了习惯任何单个工具给出的结论都要至少用另一个维度的数据去交叉验证。5.2 混合场景用 perf 看整体用 strace 看细节真实的线上问题往往不是单一因素可能既有 CPU 热点又有 IO 阻塞。我遇到过一次非常典型的情况一个批处理任务运行得异常缓慢perf 显示 CPU 热点集中在ext4_file_write_iter说明大量时间在写文件strace 进一步确认是频繁调用write系统调用每次写入的数据量特别小几十字节但文件系统在一个非常大的文件末尾追加写入。总耗时 30 分钟的任务大部分时间都花在这种零碎的写操作上。根因很有意思因为数据文件被预分配得特别大导致文件的“中间空洞”很多每次小写入都触发文件的 fragment 分配文件系统层面的元数据操作开销极大。解决办法是把小写入合并成批量大写入任务耗时从 30 分钟降到了 3 分钟。这个案例里 perf 和 strace 各承担了不同的角色perf 指出热点在文件写入strace 指出写入模式的细节两个信息缺一不可。5.3 布好安全网有些问题不用上工具也能发现前面讲了很多工具的用法最后说一个朴素的观察很多性能问题工具查了半天根因可能就是你代码里的一个低级失误。perf 和 strace 是“定位工具”不是“万能神药”。比如之前定位到某个服务 CPU 高最后发现是日志框架在 DEBUG 级别下正常输出但生产环境日志级别忘了改还在疯狂打 DEBUG 日志。再比如某个服务内存涨得飞快perf 看不出什么问题后来发现是本地缓存没设过期时间数据无限堆积GC 频繁且每次 GC 时间都很长。这类问题没有任何性能工具能替代良好的代码习惯和监控告警配置。所以我一直建议团队做两件事第一线上必须配置好日志按级别输出生产环境至少 INFO 起步绝对不能是 DEBUG第二监控告警要有CPU 超过 80% 持续 5 分钟就告警RT 超过 3 秒就告警别等问题被用户发现才开始查。工具是最后一道防线好的预防机制才是第一道。6. 常用命令速查表贴在手边的排查手册写到最后我把最常用的命令整理成一个速查表。平时排查照着这个顺序来基本不会乱关键时刻直接复制粘贴就能用。排查步骤目的命令查看负载确认 load average 情况uptime查看资源占用定位 CPU / 内存占用高的进程top -c查看进程线程 CPU定位进程内哪个线程在烧 CPUtop -H -p PIDperf 实时热点不落盘直接看进程实时热点perf top -p PID -gperf 采样分析记录 30 秒调用栈生成报告perf record -F 99 -p PID -g -- sleep 30查看采样报告按 CPU 占用率排序的函数列表perf report -g graph生成火焰图可视化调用栈方便传播perf script out.perf; stackcollapse-perf.pl out.perf out.folded; flamegraph.pl out.folded cpu.svgstrace 附加进程跟踪指定进程的系统调用strace -f -tt -T -p PID -o /tmp/strace.logstrace 统计耗时找出耗时最长的系统调用awk {print $NF, $0} /tmp/strace.log | sort -rn | head -20查看 TCP 连接状态确认是否有连接卡在握手阶段ss -tnp | grep PID最后再分享一个小技巧如果你的服务是 Java 写的在排查阻塞问题的时候别忘了jstack PID threaddump.txtJava 线程栈里能看到非常明确的阻塞点比如java.lang.Thread.State: BLOCKED、WAITING或者TIMED_WAITING。这个线程转储和 strace 交叉验证基本没有定位不了的问题。我处理过的多数生产事故流程都是先top看一眼资源再jstack看一眼线程最后用 perf 或 strace 把证据链闭合上。这套组合拳已经帮我在一个又一个“紧急事故”里稳住了局面希望对你也有用。
企业数字化 ERP 产品动态
相关推荐
Curtroller:嵌入式GUI事件驱动控制器框架,重构LVGL界面逻辑 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:08:44
Dobot+ROS抓取实战:从驱动报错到精准抓取的系统级调试指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:08:13
返利规则“写死”在代码里,每次调整都要开发介入——配置化返利引擎该怎么设计? 返利政策调整,是服装品牌渠道运营中最高频的动作之一。这个季度推新品,返利比例调高;下个季度清库存,返利规则改成“按清仓款采购量返”;旺季冲量,增加“达量返点”;淡季保底,推出“… · 2026/9/24 12:08:01
AI Agent驱动Unity自动化编译与测试:从人肉点点到机器全流程 上班摸鱼的时候刷到一个挺扎心的段子:很多团队嘴上说着“全流程自动化”,实际干活的还是人肉点点点。我一想,这不就是说我之前干的活儿吗?Unity 项目一多,每天光编译、跑测试、看日志就耗掉大半天,纯纯的人… · 2026/9/24 22:02:26
Windows中文输入栏消失?简繁体切换导致任务栏不显示输入指示器的修复方法 1. 任务栏上那个"消失"的中文输入栏,到底去哪了如果你正在用 Windows 打中文,突然发现任务栏右下角那个熟悉的"中/英"标识、或者那个悬浮的中文输入状态条不见了,先别急着怀疑系统坏了。这个现象在简繁体切换场景下尤其常… · 2026/9/24 22:02:26
Java Swing 黄金矿工小游戏:抓钩状态机与碰撞检测实战 简介:这是一份基于Java实现的黄金矿工小游戏完整源码包,面向Java初学者、课程设计学生以及想通过经典小游戏练手的开发者,帮助读者理解Swing图形界面、游戏循环、碰撞检测与资源加载等核心机制。压缩包共30个文件,约141KB… · 2026/9/24 22:02:05
体育馆场地预约系统开发实战:微信小程序+Django+Flask架构解析 体育馆场地预约平台开发手记:从电话排队到小程序一键订场做体育馆场地预约系统,最早是因为一个朋友在高校体育部上班,天天被电话轰炸:羽毛球场地有没有?今晚七点的场子被人占了能不能调?隔壁单位想包场怎么… · 2026/9/24 22:02:05
GPT-Live-1+Agora构建AI会议助手实战指南 1. 这不是“又一个AI聊天框”,而是一个能真正坐在会议室里干活的数字同事GPT‑Live‑1 Agora 实战教程:做一个能参会、操作看板的 AI 助手——这个标题里藏着三个被多数人忽略的关键动作:“能参会”、“操作看板”、“实战教程”。它不讲大模… · 2026/9/24 22:02:05
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44