Skip to content

重试与幂等

退避重试、超时控制、唯一键幂等、重试风暴。

Updated View as Markdown
For humans

重试与幂等

网络不可靠,重试是补偿手段;重试可能造成重复,幂等是补偿的补偿。面试必考组合:退避重试 + 唯一键幂等

超时控制

重试的前提是超时:请求不能无限等。

超时 含义 经验值
连接超时 建立连接的最长等待 数百毫秒到 1 秒
读超时 等待响应的最长时长 按业务 RT 定(如 3 秒)
总超时 整个调用链的上限 层层递减(调用方 < 被调用方)

要点:超时层层递减(A 调 B 的读超时小于 B 自己的处理上限),否则上游超时了,下游还在处理,请求堆积。没有超时的调用是雪崩的引线。

重试策略

策略 机制 问题
立即重试 失败马上再来 下游没恢复,白重试
固定间隔 等固定时间重试 简单,但重试风暴风险
指数退避 间隔翻倍(1s、2s、4s…) 标准方案
指数退避 + 抖动 间隔加随机值 防重试请求同时到达(惊群)
指数退避: delay = base × 2^attempt + jitter
例: 1s, 2s, 4s, 8s, 16s (上限 30s, 最多 5 次)

关键规则:

  • 只重试可重试的错误:超时、连接失败、5xx 可重试;4xx(参数错)重试无意义
  • 设最大次数:无限重试 = 无限放大故障
  • 重试风暴:大量客户端同时重试,打爆刚恢复的下游。抖动 + 上限 + 熔断配合(见熔断篇)

幂等

幂等:同一操作执行多次,结果与执行一次相同。为什么需要:重试、MQ 重复投递(at-least-once)都会产生重复。

方案 机制 适用
唯一键去重 请求带唯一 ID,处理前查重 通用(下单、支付)
数据库唯一约束 业务唯一字段建唯一索引 天然防重(订单号)
状态机幂等 状态只允许单向流转 订单状态流转
版本号/乐观锁 带版本更新,版本不符拒绝 并发更新
下单幂等流程:
1. 客户端生成 request_id(UUID)
2. 服务端查幂等表: 已存在 → 返回原结果
3. 不存在 → 处理业务 + 写幂等表(唯一键)
4. 重复请求命中唯一约束 → 返回原结果

注意:幂等表写入要原子(唯一索引兜底,查了再写有竞态);响应要缓存(重复请求返回首次结果,而不是“已存在”报错)。

面试追问

  1. 为什么重试要退避? 下游故障不会瞬间恢复,立即重试是浪费且加重负载。指数退避 + 抖动防重试风暴
  2. 哪些错误可重试? 超时、连接失败、5xx。4xx 重试无意义,别重试
  3. 幂等怎么做? 唯一键 + 幂等表(唯一约束兜底)、数据库唯一索引、状态机。消费端幂等是 MQ 场景的标配
  4. 重试和幂等什么关系? 重试产生重复,幂等消化重复。重试必须有上限,幂等必须有原子保证
  5. 超时怎么设计? 层层递减,调用方超时小于被调用方处理上限。总超时兜底
Navigation

Type to search…

↑↓ navigate↵ selectEsc close