接口偶发超时,不要先加重试:一次从日志到熔断的排查笔记
上周一个订单查询接口在高峰期偶发超时,报错率只有千分之三,却刚好都落在支付环节。第一反应是给调用方加重试,结果重试把下游压力放大了一倍,超时反而更多。这次排查让我确认了一个顺序:先分清超时发生在什么地方,再决定是修调用方、修被调用方,还是先做限流和熔断。
第一步是看日志,而不是看监控曲线。监控只能告诉你超时变多了,日志才能告诉你超时集中在哪个接口、哪个机房、哪一批请求。我们把超时请求的trace找出来,发现它们都走了同一条老链路,而且等待时间集中在下游数据库连接获取阶段,而不是业务计算阶段。也就是说,问题不在接口逻辑,而在连接池。
第二步是核对超时时间是否合理。调用方设置的超时是三秒,下游在高峰期的P99已经接近两点八秒,留给网络抖动和排队的余量几乎为零。把超时时间盲目调大,只会让排队更长;把超时调小,又会误杀正常请求。更稳妥的做法是先把连接池、慢查询和锁等待分开看:连接池是否打满,慢查询是否集中在某几张表,是否有长事务占着连接不放。
我们当时的根因是两个叠加:一个定时任务在高峰期跑全量扫描,占用了大量连接;同时连接池的最大连接数按平时峰值设置,没有给突发留余量。处理顺序也很重要:先停掉高峰期的全量任务,把慢查询改成按主键分批;再把连接池上限按高峰期实测值上调一档,并把等待队列的超时单独设置,避免一个慢请求拖住一整批请求。
第三步才是谈重试和熔断。重试只适合幂等请求,而且必须加退避和次数上限,不能对所有超时无差别重试。支付、下单这类非幂等操作,先保证幂等键,再谈重试。熔断则是保护自己的手段:当某个下游连续超时达到阈值,先快速失败并返回可降级的提示,而不是让所有请求都在原地排队等死。熔断打开后,还要有半开探测,确认下游恢复再逐步放量。
最后留一个检查清单给自己:超时先看trace和分位值,再看连接池和慢查询,最后才动重试和熔断;任何一次改动只改一个变量,观察十分钟再动下一个。接口超时很少是单个参数的问题,多数是排队、锁和突发流量叠加的结果。把排查顺序固定下来,下次就不用在高峰期凭感觉调参数了。
- 点赞
- 收藏
- 关注作者
评论(0)