接口超时与重试风暴:从超时分级到熔断限流的实战
一次大促复盘会上,监控图上的曲线让人印象深刻:上游一个核心接口只是偶发抖动,平均耗时从80毫秒涨到500毫秒,调用方的流量却在几分钟内翻了四倍,最后上游直接被拖垮。根因并不在上游,而在调用方的重试——每个请求默认重试三次,超时时间又设得很大,一次抖动就被放大成一场重试风暴。超时和重试是每个后端系统都会遇到的基础问题,但配错了参数,保护机制本身就会变成故障放大器。
一、超时不是一个数,要分级设置
很多项目只配一个全局超时,比如统一5秒,这是最常见的坑。一次调用至少包含三个阶段:建立连接、等待服务端处理、读取响应,对应连接超时、读超时和写超时。连接超时可以短一些,一般1到2秒就够了,建连失败多半是网络或目标不可达,等再久也没用;读超时要按接口的正常耗时分布来定,建议取P99的2到3倍,同时留出一个上限;写超时则看请求体大小,大文件上传要单独放宽。更重要的是区分接口:核心支付链路和普通查询接口不能共用一套超时,慢接口的超时要单独配置,避免一个慢接口拖垮整个线程池。
二、重试只给值得重试的请求
重试的第一条铁律是只重试幂等操作。查询类接口天然可重试,创建订单、扣款这类写操作必须先确认幂等键或有去重机制,否则一次重试可能产生两笔订单。第二条是只重试值得重试的错误:连接失败、服务端503、网关超时可以重试,400参数错误、401鉴权失败、业务校验失败重试一百次也不会成功。第三条是给重试设总预算:单次请求重试不超过2次,全局用指数退避加随机抖动,比如第一次等200毫秒,第二次等400毫秒,再叠加0到100毫秒的随机抖动,避免所有客户端在同一时刻集体重试,形成新的尖峰。
三、熔断与限流是最后一道防线
即使超时和重试都配对了,依赖方持续故障时仍需要熔断:当最近一段时间错误率超过阈值,比如50%,就快速失败一段时间,不再发请求,给依赖方喘息的机会;半开状态下放少量探测请求,成功了再逐步恢复。调用方还要做并发限流和线程池隔离,核心接口和非核心接口用不同的线程池,避免非核心接口的慢请求挤占核心接口的资源。配合降级策略,读接口可以返回缓存数据,写接口可以提示稍后重试,至少保证核心链路可用。
四、一个可以直接抄的检查清单
上线前按这张清单自查一遍:连接超时、读超时、写超时是否分开配置;每个接口的超时是否按P99设定;写操作有没有幂等键;重试次数、退避策略、抖动是否配好;熔断阈值、半开探测、降级开关是否都有;超时和重试指标是否接入了监控和告警。很多故障复盘到最后都会发现,问题不在代码逻辑,而在这些默认值上。
超时和重试的本质是取舍:超时太短会误杀正常请求,太长会拖垮调用方;重试太少会放过偶发抖动,太多会放大故障。把超时分级、重试设限、熔断兜底这三件事做对,系统在依赖抖动时才能稳住,而不是被自己的保护机制推倒。
- 点赞
- 收藏
- 关注作者
评论(0)