返回首页

API 性能排障面试实战 — 从 200ms 飙到 3 秒的排查思路

📅 创建于 2026-06-04 🔄 更新于 2026-06-04 📝 440 字

API 性能排障面试实战 — 从 200ms 飙到 3 秒的排查思路

来源:波波 | 发布日期:2026-06-02

场景还原

订单查询接口 /order/detail 的 P99 耗时从 200ms 飙升到 3.2s:

  • 正常表现: P99 ≈ 200ms,QPS ≈ 500
  • 异常表现: P99 → 3.2s,持续 10 分钟后恢复至 800ms
  • 监控表象: CPU 60%,内存正常,数据库 CPU 40%,无死锁日志
  • 业务反馈: 用户端加载订单详情明显卡顿

第一直觉:不是全系统崩溃,也不是数据库整体过载,更像是某个依赖或特定参数引发的慢查询或阻塞。

系统化排查方法论

第一层:确认影响范围(定界)

通过监控查看 P99/P95/P50 变化曲线,判断是少量长尾还是整体漂移

  • 整体漂移 → 公共依赖出了问题(数据库、缓存、RPC 服务)
  • 少量长尾 → 特定参数触发了慢查询或大 key

同时确认是否所有实例都慢(负载均衡 vs 单机问题),以及错误率是否上升。

第二层:调用链分析(APM 定位瓶颈)

在 APM 平台(SkyWalking、Pinpoint 等)查看该接口的 trace 调用链:

  • MySQL 慢查询: 抓慢 SQL → EXPLAIN → 看锁等待
  • Redis 慢命令: SLOWLOG GET 10 → 检查 big key
  • 下游 RPC: 检查下游服务状态、网络延迟
  • 业务代码: 看日志中是否有新增循环批量操作或异常兜底逻辑

第三层:数据库慢查询深入诊断

如果 90% 时间花在一条简单的 WHERE order_id = ? 上,可能的原因及排查方式:

可能原因 排查方法 解决方案
索引失效 EXPLAIN 看 type 是否为 ALL/index 检查隐式类型转换、函数操作、OR 条件
统计信息陈旧 SHOW INDEX 看 Cardinality ANALYZE TABLE 更新统计信息
锁竞争 SHOW ENGINE INNODB STATUS 优化事务隔离级别,减少行锁范围
硬件/I/O 瓶颈 iostat 看延迟,top 看 wa 排查磁盘故障或换 SSD
Buffer pool 污染 大量冷数据涌入将热数据挤出 冷热分离或增大 buffer pool

第四层:连接池/线程池排查

HikariCP 最大连接数=20,通过 Micrometer 监控 hikaricp_connections_pending(等待连接数)和 hikaricp_connection_timeout

  • pending > 0 持续 → 连接池不够用
  • jstack 看是否大量线程处于 TIMED_WAITING → 等待连接池获取连接

第五层:GC 问题定位

Java 8 + CMS 场景下,三种快速定位方法:

  1. jstat -gcutil <pid> 1000 — 看 YGC/FGC/FGCT 频率和耗时
  2. jmap -histo:live <pid> \| head -20 — 看存活对象分布
  3. GC 日志 + GCViewer/GCEasy — 分析 Full GC 频率、STW 时间、晋升率

生产推荐挂载 Arthas,用 dashboard 实时看 GC 和内存。

常见 GC 问题:

  • 内存泄漏: Old Gen 持续增长 → jmap 导出 heap dump,MAT 分析
  • 频繁 Young GC: Eden 区太小 → 调整 -Xmn / -XX:SurvivorRatio
  • CMS 并发模式失败: Old Gen 增长过快 → 增大 CMS 触发阈值

第六层:Redis 慢命令排查

场景:HGETALL 读取 100 万字段的 Hash 导致 Redis 阻塞

预防:

  • 禁止 KEYS,改用 SCAN
  • 大 key 拆分,Hash 单 key 字段数 ≤ 1000
  • redis-cli --bigkeys 定期扫描

发现:

  • CONFIG SET slowlog-log-slower-than 10000 + SLOWLOG GET 10
  • APM 中对 Redis 调用做埋点

临时处理: 业务层改为 HMGET 只取必要字段,或用本地缓存(Caffeine)减少 Redis 压力。

完整排查脑图

收到告警 → 接口耗时飙升
  ├─ 1. 确定范围:P99/P95 曲线 → 整体漂移 or 长尾
  ├─ 2. 调用链:MySQL 慢查询 / Redis 慢命令 / RPC 延迟 / 业务代码耗时
  ├─ 3. 系统层:top/vmstat/iostat → jstat/jstack → GC 日志
  ├─ 4. 中间件:数据库连接数/慢查询/死锁,Redis 慢查询/内存,MQ 堆积
  └─ 5. 变更关联:最近发布?配置变更?依赖升级?→ 回滚验证

优先恢复,再找根因。kill 慢查询、临时扩大连接数、dump 堆内存、回滚版本都是合理的第一反应。

面试回答模板

"第一,确定影响范围和特征——看 P99/P95 变化,判断少量长尾还是整体漂移。 第二,借助调用链定位瓶颈——APM 上看 trace,定位耗时在哪一层。 第三,排查资源池和 GC——jstack 看线程状态,jstat 看 GC 频率。 第四,检查变更和异常——最近的发布、配置变更、依赖升级,必要时回滚。 最后,优先恢复,再找根因。"

关联页面

页面 关联点
fullstack-performance-troubleshooting 全栈性能排障方法论全景
online-troubleshooting-checklist 线上四维速查命令清单
server-performance-four-dimensions 服务器四维排查法(Netflix 黄金 60 秒)
cpu-spike-troubleshooting-guide CPU 飙高专项排查
ops-interview-50-questions 运维经典面试 50 题
devops-interview-guide DevOps 面试指南(云原生侧重)