AI 求职每日一课 · 2026-09-17
AI JOB COURSE · WEEK 2 · DAY 4

幂等与重试:
失败后不重复造成副作用

为有副作用的工具调用加稳定业务键、状态对账、退避预算和人工接管。

02

为什么今天学这个

昨天解决工具注册、超时与错误分类;今天处理最危险的未知状态:请求可能已到达支付或建单系统,却在响应前超时。重试不能换业务 key。
03

三个核心要点

稳定 key
同一业务意图复用同一幂等键。
先对账
超时不等于失败,先查询外部状态。
有预算
只重试瞬时错误,设置总 deadline。
04

最小可运行示例

async function run(api, input, max = 3) {
  const key = input.requestId;
  for (let i = 0; i < max; i++) {
    try { return await api.create({...input, idempotencyKey:key}); }
    catch (e) {
      if (!['TIMEOUT','503'].includes(e.code)) throw e;
      const known = await api.findByIdempotencyKey(key);
      if (known) return known;
      await new Promise(r => setTimeout(r, 100 * 2 ** i));
    }
  }
  throw Error('RETRY_BUDGET_EXHAUSTED');
}
05

生产环境会怎么翻车

  • 每次重试生成新 key:重复扣款;从订单号稳定派生。
  • 把超时当失败:外部已成功;先查询,无法确认则人工处理。
  • 无限退避:队列堆积;设最大次数、总时限和死信。
  • 只在 SDK 层幂等:入口统一生成并贯穿审计链。
06

动手练习

给执行器增加 create_ticket:连续两次模拟超时,第三次用同一 key 查询已创建。验收:只产生一个 ticket,日志区分 UNKNOWN_STATERETRYABLE
07

面试表达

30 秒回答

稳定幂等键贯穿所有有副作用的下游;超时先查状态,确认未执行且错误可重试才用同一 key 退避重试,并设总时限和人工接管。

追问

下游不支持幂等时,在本服务落库请求键和结果,用唯一约束合并并发;但跨系统未知状态仍需对账。

08

今日自测

基础
为什么复用 key?让服务端识别重复请求并返回已有结果。
取舍
500 一定重试吗?不一定,先判断是否已产生副作用。
场景
支付超时第一步?用同一 key 查询状态。
09

来源与明日

按 P 切换投影