一次接口响应变慢排查:最终发现是线程池参数和重试策略叠加导致的

发布时间:2026/6/10 7:18:14
一次接口响应变慢排查:最终发现是线程池参数和重试策略叠加导致的
背景有一次线上接口突然变慢平均响应时间从几百毫秒涨到一秒多。最开始大家都在看数据库、看网络、看下游接口但查了一圈都没有特别明显的异常。后来顺着调用链一点点拆才发现问题并不是某一个点“特别慢”而是线程池参数和重试策略叠加后把整体延迟拉高了。为什么这种问题容易误判这类问题的麻烦之处在于单次调用看起来没那么离谱慢 SQL 不明显下游接口偶尔抖动但也没到不可用业务日志里只有“接口变慢”没有直接报错结果就是每一层看起来都“有点问题”但又不像根因。先看线程池队列太长不代表系统稳定当时我们的线程池配置偏保守核心线程数不高队列长度却比较大。平时流量平稳时没什么问题但一遇到下游波动请求就开始在队列里排队。表面上看线程池没有拒绝任务好像很稳定实际上用户请求已经在无声地等待了。这类配置的典型风险是拒绝少但延迟高监控容易误判为“系统还能扛”高峰期耗时不断堆积再看重试一次小抖动被放大成整条链路变慢更关键的是我们在下游调用上加了重试而且重试间隔和超时时间都不算短。于是出现了这样的情况第一次调用抖动业务线程进入等待重试再次占用线程队列继续积压单看重试逻辑它是为了提高成功率单看线程池它也不是完全不合理。但两者叠加之后系统的平均响应时间就被整体拉上去了。这类问题怎么查更有效后来我比较认可的排查方式是分成三步先看线程池活跃线程数、队列长度和拒绝数再看慢请求里有多少次发生了重试最后把重试耗时和排队耗时加起来看总账如果只盯着接口平均耗时很难意识到“排队时间”其实已经占了大头。这次排查给我的几个提醒线程池的目标不是“尽量不拒绝”而是“在系统可控范围内处理请求”队列过长会掩盖问题让延迟在系统内部慢慢堆积重试不是免费的提高成功率的同时也会放大资源占用涉及外部依赖的链路必须同时看超时、重试和并发配置总结这次接口变慢最容易让人误判的地方就是每个点单独看都不算致命真正的根因在于线程池参数和重试策略共同作用。排查线上慢请求时我越来越觉得“组合效应”比“单点故障”更值得警惕。如果系统已经接了很多外部服务这类问题以后大概率还会再遇到提前把排队时间和重试行为纳入监控会省很多事。