← 返回题目列表

前端请求重试应该如何设计?

高频 中等 第 5 / 26 题 更新于 2026/07/28
前端网络请求重试幂等指数退避

简化版

请求重试适合临时网络错误、超时、部分 5xx,但不应无脑重试所有请求。设计时要考虑幂等性、最大次数、指数退避、抖动、取消机制和用户提示。非幂等操作如支付、下单要特别谨慎。

详细版

可重试场景:

  • 网络短暂失败。
  • 请求超时。
  • 502、503、504。
  • 429 在服务端允许时延迟重试。

不适合随意重试:

  • 400 参数错误。
  • 401/403 权限问题。
  • 非幂等 POST。
  • 支付、创建订单等敏感操作。

策略:

  • 设置最大重试次数。
  • 指数退避延迟。
  • 加随机抖动避免同时重试。
  • 支持取消。
  • 记录重试日志。

完整版教学

一、为什么不能无脑重试

重试能提升弱网成功率,但也可能放大故障。如果服务器已经很忙,大量客户端同时重试,会让服务雪上加霜。

如果请求是非幂等的,重试还可能造成重复下单、重复扣款、重复提交。

二、幂等性是关键

幂等表示同一个操作执行一次和执行多次结果一致。GET 通常天然幂等,部分 PUT/DELETE 可以设计成幂等,POST 则不一定。

对于创建订单这类操作,服务端应提供幂等键。前端重试时带同一个幂等键,服务端保证只创建一次。

三、指数退避和抖动

指数退避是每次失败后等待更久再重试,例如 1s、2s、4s。

抖动是在延迟中加入随机值,避免大量客户端在同一时间再次请求,造成重试风暴。没有抖动时,客户端会按相同节拍重新同步,即使指数增长也可能周期性冲击服务端。

四、面试追问与工程落地

面试官可能问:“上传文件失败要怎么重试?”

小文件可以整体重试,大文件更适合分片上传和断点续传。每个分片可单独重试,最终服务端合并。这样失败成本更低。

工程中请求重试应该放在统一请求层,不要每个业务页面自己写一套。

五、退避算法与 Retry-After

固定 1 秒重试会让同一时刻失败的客户端再次同步撞击服务。第 n 次退避可先算上限,再用 full jitter 随机取值:

cap(n) = min(maxDelay, base × 2^n)
delay(n) = random(0, cap(n))

若 base=500ms、maxDelay=8000ms,第 0–4 次上限依次为 500、1000、2000、4000、8000ms;10000 个客户端会被随机摊开,而不是都在整秒同时请求。

结果默认建议原因
网络中断/超时条件重试可能是瞬态,但结果未知
429尊重 Retry-After服务端明确限流
502/503/504有界重试网关/服务可能恢复
400/422不重试相同参数不会自愈
401/403刷新身份或停止权限问题不是瞬态

重试预算要包含“首次请求 + 重试次数 + 总耗时”;只限制次数,单次超时很长时仍会拖死用户。

六、幂等键和一次操作的身份

支付请求超时不代表支付失败,可能是服务器已扣款但响应丢失。客户端若生成新的订单请求重试,就会重复执行;正确方式是为一次业务意图生成稳定幂等键:

POST /orders
Idempotency-Key: 8f2c...same-for-all-retries

服务端原子记录 key、请求摘要和最终结果。相同 key + 相同请求返回原结果;相同 key + 不同参数应拒绝。幂等记录还要设置与业务重试窗口匹配的保留时间,例如允许 24 小时恢复就不能 5 分钟删除。

重试层必须支持 AbortSignal、总 deadline 和可观测日志,记录 attempt、等待时间、最终状态。前台请求通常重试 2–3 次已足够,后台任务可更久但应进入队列、熔断和告警体系。

当服务端已明确返回不可重试的业务错误时,应立即结束循环,避免把确定性失败变成额外负载。

七、常见误区与追问

  • 误区:任何 5xx 都应该无限重试。 永久错误和过载会被放大,必须有次数、总时限和熔断。
  • 误区:POST 天生不能重试。 它默认不幂等,但可通过稳定幂等键和服务端原子记录安全重试。
  • 误区:请求超时就证明服务端没有执行。 响应可能丢失,操作状态未知,应查询或按同一幂等键重试。
  • 追问:为什么指数退避还要 jitter? 避免大量客户端在相同指数时刻同步形成重试风暴。
  • 追问:429 应等待多久? 优先解析服务端 Retry-After,并受客户端总 deadline 限制。
  • 追问:PUT/DELETE 一定幂等吗? HTTP 语义期望幂等,但具体业务副作用和实现仍需验证。
  • 追问:怎样避免重试拖慢用户? 设置单次超时、总 deadline、最大次数,并对非关键请求快速降级。

八、加强记忆

  1. 先分类:只重试瞬态、可恢复错误,不重试参数和权限错误。
  2. 再问幂等:读取通常安全,写操作需要稳定幂等键与服务端保证。
  3. 控制节奏:指数退避加随机抖动,429 尊重 Retry-After。
  4. 限制预算:最大次数、单次超时和总 deadline 同时存在。
  5. 支持取消:用户离开或新请求替代时停止等待与后续重试。
  6. 保持可观测:记录每次 attempt、延迟、结果和幂等键关联状态。