Skip to content
应用运行时异常排查 · 第 4 篇 / 共 4 篇
领域生产问题
专题应用运行时排障专题
当前序列应用运行时异常排查
阅读位置第 4 篇 / 共 4 篇当前专题第 1 个序列 / 共 3 个序列

生产问题:接口 RT 飙升但 CPU 不高时怎么排查

很多线上接口超时问题,最迷惑人的地方在于:

  • CPU 不高
  • 机器负载不夸张
  • 服务没有直接挂掉
  • 但 RT 一直上涨,请求开始排队

这类问题往往不是“机器忙不过来”,而是某个关键资源被卡住了。

先说结论

接口 RT 飙升但 CPU 不高时,最实用的排查顺序通常是:

  1. 先确认是整体变慢,还是少数接口变慢
  2. 再看线程是不是在等待数据库、Redis、HTTP 或锁
  3. 再看线程池、连接池、队列有没有被占满
  4. 最后再回到 SQL、缓存命中率和下游依赖上找根因

这种问题大多数都属于:

  • 等待时间太长
  • 排队时间太长
  • 少量慢点把整条链路拖住了

更进一步说,这类问题最重要的不是证明“机器不忙”,而是找出:

  • 线程到底在等谁
  • 请求到底卡在哪一段
  • 是执行慢,还是排队慢

一、先把现象分清楚

先判断下面几件事:

  • 是单个接口变慢,还是整个服务都慢
  • 是偶发尖刺,还是持续性上涨
  • 是入口 RT 变高,还是下游调用耗时变高

如果只有某一个接口慢,优先怀疑:

  • SQL
  • 缓存
  • 远程调用
  • 锁竞争

如果整个服务一起慢,优先怀疑:

  • 线程池
  • 数据库连接池
  • Redis 连接池
  • 某个公共下游抖动

还要补一个判断:

  • 是高峰流量触发的
  • 还是最近发版、配置变更、缓存失效触发的

二、为什么 CPU 不高也会超时

因为很多接口不是在做计算,而是在等。

常见等待点包括:

  • 等数据库连接
  • 等 SQL 返回
  • 等 Redis 返回
  • 等 HTTP 或 RPC 下游
  • 等锁
  • 等线程池排队

所以 CPU 低并不能说明服务没问题,它只能说明:

  • 线程并没有一直在执行计算

但线程很可能大量卡在 WAITINGTIMED_WAITING 或阻塞 IO 上。

这也是很多线上排障最容易绕偏的地方:

  • 机器不高,不代表服务不慢
  • 线程没在算,不代表线程没被占住

三、先看线程在等什么

这一类问题里,线程栈通常很有价值。

重点看:

  • 线程都卡在什么调用栈
  • 是不是大量线程都停在同一个方法
  • 是不是有很多线程卡在连接池获取、网络读写或锁等待

如果大量线程都卡在:

  • getConnection
  • socketRead
  • Future.get
  • CountDownLatch.await
  • LockSupport.park

通常就说明:

  • 不是 CPU 问题
  • 是等待链路出了问题

如果线程栈里大量出现同一类等待点,通常已经能把问题从“整个系统都慢”缩小到某一层。

四、最常见的四类根因

1. 下游接口变慢

这是最常见的一类。

比如:

  • 订单服务查用户画像
  • 用户服务又调推荐服务
  • 推荐服务再查 ES

只要中间某一跳 RT 抖起来,入口接口就会被一起拖慢。

这时常见特征是:

  • 本服务 CPU 不高
  • 业务线程都在等下游返回
  • 超时数逐渐升高

2. 数据库慢查询或连接池耗尽

数据库问题的典型表现是:

  • 某一批接口一起慢
  • 线程大量卡在取连接或执行 SQL
  • 应用日志出现连接获取超时

很多人会先加连接池大小,但如果根因是慢 SQL,连接数加大后往往只是把数据库压得更狠。

3. 缓存命中率下降

比如:

  • 热 Key 失效
  • 批量 Key 同时过期
  • Redis 抖动导致大量请求回源

这时业务线程会突然把流量压到数据库上,进而出现:

  • 数据库变慢
  • 线程池排队
  • 接口 RT 一起上涨

4. 线程池和异步编排设计不合理

很常见的链路是:

  • 入口请求进来
  • 扔到异步线程池
  • 线程池里再调多个下游
  • 某个下游超时后线程迟迟不释放

最终表现为:

  • 线程池队列堆积
  • 拒绝策略开始触发
  • 主线程也被拖慢

5. 锁竞争或串行化热点

比如:

  • 某个本地锁粒度太大
  • 某个用户、订单、资源被串行处理
  • 某个共享对象争用严重

这类问题 CPU 也不一定高,但等待会很明显。

五、一个更实用的排查顺序

第一步:看监控面板

先同时看:

  • RT
  • QPS
  • 错误率
  • 超时数
  • 线程池活跃数
  • 数据库连接池使用率
  • Redis 和 HTTP 客户端连接池使用率

如果 RT 上涨而 QPS 没明显增加,通常更像是:

  • 下游变慢
  • 线程被卡住

第二步:看线程栈

目标不是看所有线程,而是找出:

  • 大多数业务线程卡在哪一层

如果大量线程集中停在同一处,根因方向通常已经比较清楚了。

第三步:看入口日志与下游耗时

重点是把接口总耗时拆开:

  • 业务计算耗时
  • SQL 耗时
  • Redis 耗时
  • RPC 耗时

如果有网关、BFF、聚合层,还应该把:

  • 网关排队
  • 下游并发等待
  • 序列化/反序列化

也拆出来看。

很多问题一拆就能看见:

  • 真正慢的不是接口本身
  • 而是某个子步骤突然变慢

第四步:确认有没有排队

要特别看:

  • 线程池队列长度
  • Tomcat 或 Undertow 工作线程状态
  • 数据库连接池等待时间

接口超时很多时候不是执行慢,而是:

  • 前面已经排了太久

第五步:看最近有没有变更

这一步很容易被忽略,但线上特别重要:

  • 最近是否发版
  • 是否改过线程池参数
  • 是否改过超时配置
  • 是否有缓存失效、索引变更、下游切流

很多 RT 问题不是自然发生,而是某个小改动把等待链路拉长了。

六、一个典型案例怎么理解

比如订单详情接口平时 80ms,某次活动期间涨到 2s。

排查后发现:

  • CPU 只有 35%
  • 线程池活跃线程接近上限
  • 大量线程卡在调用用户画像服务
  • 用户画像服务又因为 Redis 热点失效回源数据库

最后真正的问题不是订单接口本身,而是:

  • 热点缓存失效
  • 下游回源变慢
  • 上游线程池被拖住

这类问题非常典型,说明接口超时要看整条调用链,而不是只盯入口接口。

七、怎么治理更稳

更稳妥的治理方式通常包括:

  • 为下游调用设置明确超时
  • 业务线程池按任务类型拆分
  • 关键缓存做热点保护和过期抖动
  • SQL 和慢查询治理常态化
  • 入口增加降级、限流和兜底逻辑

如果是聚合接口,还要特别注意:

  • 不要无限制并发下游
  • 不要在异步线程里堆阻塞操作

还要补两件事:

  • 给关键等待点做分段埋点
  • 让线程池、连接池和下游超时有明确边界

一句话总结

接口 RT 飙升但 CPU 不高时,最常见的真相不是“服务没压力”,而是:

  • 线程在等待
  • 请求在排队
  • 下游在变慢

把线程状态、连接池、线程池、排队时长和下游耗时一起看,通常会比只盯机器指标有效得多。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 回看前文会更完整线程池打满时怎么排查适合把 CPU、Full GC、线程池和接口超时这类应用层异常放在一组里看。应用运行时排障专题 · 应用运行时异常排查同一序列 · 回看前文会更完整Full GC 频繁时怎么排查适合把 CPU、Full GC、线程池和接口超时这类应用层异常放在一组里看。应用运行时排障专题 · 应用运行时异常排查同专题其他序列 · 共享标签:线上排障、案例排障接口超时排查为什么要区分 RT 和 queue wait适合把线程死锁、CPU 高、Full GC、接口超时和 OOM 现场保留放在一条运行时排障主线上看。应用运行时排障专题 · 应用运行时故障的现场与根因收敛同专题其他序列 · 共享标签:线上排障、案例排障线程池积压时怎么判断是慢任务还是流量放大适合把线程死锁、CPU 高、Full GC、接口超时和 OOM 现场保留放在一条运行时排障主线上看。应用运行时排障专题 · 应用运行时故障的现场与根因收敛跨专题关联 · 共享标签:线上排障、案例排障磁盘打满后为什么删除文件不一定立刻生效适合把 Redis 抖动、MySQL 连接打满、MQ 积压、ES 发黄、ClickHouse 合并堆积和磁盘打满放在同一条基础设施排障主线上看。数据与基础设施排障专题 · 数据与基础设施故障的分层排查跨专题关联 · 共享标签:线上排障、案例排障大 Header、buffer、timeout 问题怎么排查适合把 location 匹配、缓冲区和负载均衡放在一起看。容器与站点部署专题 · Nginx 进阶路由与代理治理
继续阅读应用运行时异常排查当前序列第 4 篇 / 共 4 篇当前专题第 1 个序列 / 共 3 个序列
往前看
上一篇线程池打满时怎么排查回到当前序列上一章上一序列业务稳定性与治理实践从第 1 篇开始:支付回调幂等到底该怎么落地
往后看
下一序列应用运行时典型故障案例从第 1 篇开始:Redis 热 Key 突增时怎么止血和回查

把零散经验整理成可查、可复用、可持续更新的企业级知识门户