本文目录导读:

这是一个非常经典且高价值的问题,系统卡顿的排查之所以耗时,往往是因为问题重现难、证据链碎片化、分析工具不顺手。
要提升排查效率,核心思路是:从“人工探案”转变为“自动化取证”和“标准化诊断”。
以下是经过实战验证的、可落地的提升路径,分为四个层级:
第一层:建立“黄金指标”监控(前置准备)
很多卡顿查不出来,是因为没有数据,必须提前布好“天网”。
- 全链路追踪(APM):
- 核心动作: 为所有请求生成唯一 Trace ID,贯穿网关 -> 应用 -> 数据库 -> 第三方。
- 价值: 出现卡顿,直接通过 Trace ID 查到是哪个环节耗时最长(是网络?是DB?还是某段代码?),无需逐台机器登录。
- 分层监控仪表盘(Grafana/Prometheus):
- 建立“黄金信号”看板: 同时展示 CPU、内存、磁盘 I/O、网络 I/O、GC 频率、连接池水位。
- 关键技巧: 设置“阈值的同比/环比”告警,CPU 使用率比上周同期突增 50%”,而不是简单的“CPU > 90%”,这能帮你抓住异常波动,而非静态值。
第二层:标准化“快照”采集(现场保护)
卡顿发生时,如果不清楚该抓什么,重启后现场就破坏了。
- “一键快照”脚本(建议放在代码仓库或运维工具中):
- CPU 高:
top -H -p <PID>找出线程,jstack <PID>抓堆栈。 - 内存/GC 问题:
jstat -gcutil <PID> 1000 10观察 GC 频率,jmap -dump:live,format=b,file=heap.hprof <PID>抓堆。 - 磁盘 I/O:
iostat -x 1查看await和%util。 - 数据库慢查: 立即开启
slow_query_log并设置long_query_time=1。
- CPU 高:
- 建立“异常自动 dump”机制:
- 做法: 在应用配置中设置,当某个接口 P99 延迟超过阈值(如 5s)时,自动执行
jstack和jmap并上传到日志中心。 - 价值: 人还在睡觉,系统已经帮你把“案发现场”的指纹采集好了。
- 做法: 在应用配置中设置,当某个接口 P99 延迟超过阈值(如 5s)时,自动执行
第三层:结构化排查路径(标准流程)
最忌讳的是“东看看西看看”,使用标准化的决策树:
第一步:看全局,还是局部?
- 所有接口都慢? -> 查基础资源(CPU/内存/磁盘/网络)、中间件(DB负载、Redis/ MQ 挂机)。
- 仅某一个接口慢? -> 查代码逻辑(死循环、锁竞争、大量对象创建)、依赖服务(下游响应慢)、SQL 语句。
第二步:如果是“所有接口都慢”:
- 看 CPU:
top-> CPU高? ->jstack看线程 -> 是业务线程?GC线程?还是系统线程? - 看 GC:
jstat->FGC频繁且YG持续高? -> 内存泄漏或对象创建失控 -> 抓 Heap Dump。 - 看磁盘:
iostat->%util接近100%? -> 大量日志写入?DB 刷盘慢?SWAP 交换? - 看锁: 看线程间是否有锁竞争,或者进入了死锁状态。
第三步:如果是“仅一个接口慢”:
- 链路追踪(APM): 直接看 Span。
- 查数据库:
show processlist-> 是否有锁等待?是否有慢 SQL 占用了 CPU? - 查依赖: 调用了外部HTTP/RPC? 服务超时是否设置了合理的
timeout? - 查本地日志: 在接口入口处打印前后时间戳,计算具体耗时点。
第四层:工具与自动化的“外挂”
把重复工作交给工具,用工具替代人肉分析:
- AI 告警收敛与根因推荐(AIOps):
使用 Datadog / SkyWalking / 自建算法,当告警爆发(如:10 台机器同时告警 CPU 高)时,系统自动关联出“数据库慢查”是根因,而不是让你一台台检查。
- 自带火焰图生成(Async-profiler):
- 在代码中埋点,当接口延迟超过 500ms 时,利用
async-profiler自动生成 CPU 或 Wall Clock 火焰图。一张图就能告诉你代码慢在哪里(是正则匹配?是序列化?是加锁?)。
- 在代码中埋点,当接口延迟超过 500ms 时,利用
- 自动化慢查分析器:
- 将慢查询日志(
slow_query_log)导入分析工具,自动找出rows_examined高但rows_sent少的 SQL(典型索引失效或全表扫描)。
- 将慢查询日志(
效率提升的关键 Checklist
| 现状(低效) | 目标(高效) |
|---|---|
| 等用户投诉后,手动登录服务器查 | 系统卡顿时自动告警并采集jstack和heap dump |
| 凭经验猜:“可能是数据库慢” | 看 APM 链路追踪,精确定位到 DB Query 阶段 |
用 tail -f 看日志,肉眼搜关键字 |
日志平台集中检索,聚合 error 日志及 trace_id |
| 人工比较“这次和上次哪里不一样” | 指标库自动同比/环比,标注出突增的异常指标 |
| 排查后手动写报告 | 自动生成时间线回顾(发生时间、根因、影响范围) |
一句话建议: 不要试图优化某一次的排查速度,而是花 1-2 天时间把第一层(监控)和第二层(快照采集)自动化建设好。当系统卡顿发生时,数据已经整齐地摆在你面前,效率提升就是顺理成章的事。