防止服务器雪崩需节制重试:只对临时故障(如503/504、网络超时)谨慎重试,禁用永久错误(400/401/403/404/422)重试;采用带抖动的指数退避;配合熔断、限流与幂等设计。

防止高频失败请求引发服务器雪崩,关键不是“多试几次”,而是让重试行为本身具备节制性、区分性和退避意识。核心思路是:不盲目重试,只对可恢复错误谨慎重试;不密集重试,用指数退避拉开时间间隔;不限制重试,用熔断机制主动暂停。
识别并过滤不可重试的错误
重试前必须做错误分类判断,避免对永久性错误反复施压:
- 明确拒绝重试:400(参数错误)、401(未授权)、403(禁止)、404(不存在)、422(语义错误)等客户端问题,重试毫无意义,应直接上报并终止
- 谨慎重试:500(内部错误)需结合业务上下文判断——若日志中伴随“DB connection timeout”或“upstream timeout”,可视为临时故障;若固定返回相同堆栈,则大概率是代码缺陷,不应重试
-
优先重试:网络层错误(如 Axios 的
ERR_NETWORK、ERR_CONNECTION_TIMEOUT)和 503/504 状态码,属于典型临时故障,适合纳入重试范围
采用指数退避 + 随机抖动策略
固定间隔重试(如每次等1秒)在并发场景下极易形成请求尖峰,改用带抖动的指数退避可显著打散请求节奏:
- 第1次失败后等待
1000ms - 第2次失败后等待
2000ms ± 200ms(加入±200ms随机偏移) - 第3次失败后等待
4000ms ± 400ms - 后续依次翻倍,并始终叠加 10%~20% 随机抖动,避免重试请求同步抵达
引入熔断与请求限流双保险
当失败率持续超标时,主动“踩刹车”,保护后端与自身稳定性:
立即学习“Java免费学习笔记(深入)”;
- 熔断开关:例如连续5次请求中失败≥4次,自动开启熔断(持续30秒),期间所有同类请求直接拒绝,返回兜底数据或友好提示
- 并发请求数限制:对同一接口的重试任务,使用信号量(Semaphore)控制最大并发数(如≤3),避免多个失败请求同时发起重试风暴
- 全局失败计数器:按接口维度统计单位时间(如60秒)内失败次数,超阈值(如≥20次)则临时降级,跳过重试逻辑
确保重试操作幂等且无副作用
非幂等请求(如 POST 创建订单)重复提交会引发资损,必须从源头规避:
- 对写操作,前端生成唯一请求 ID(如
v4 UUID)并透传至服务端,由后端做幂等校验(如 Redis SETNX 记录已处理 ID) - 读操作(GET)默认可安全重试;写操作(POST/PUT/DELETE)需配合服务端幂等设计,否则前端不应自动重试
- 用户显式触发动作(如点击“提交订单”按钮)应禁用重试,仅对后台静默请求(如心跳、状态轮询)启用智能重试


















