首页/开发/系统分析与架构设计速查/幂等键(Idempotency Key)

幂等键(Idempotency Key)

客户端为每次业务操作生成唯一键,服务端首次执行后缓存结果,重复请求返回同一结果;适用于支付、下单等不可重复的写操作。

幂等键是什么

幂等键让同一个业务操作可以安全重试:客户端为每次操作生成唯一键,服务端首次执行后保存结果,重复请求直接返回同一结果而不再执行。它解决网络超时、客户端重试与消息重投导致的重复提交,适用于支付、下单、扣款等不可重复的写操作。

服务端怎么实现

为幂等键建唯一约束,请求进来先尝试插入记录,插入成功才执行业务;插入冲突说明是重复请求,返回已保存的结果。要额外处理三种情况:并发同键请求(后到者等待或收到处理中提示)、键与请求参数不一致(返回冲突而不是执行新操作)、缓存过期后同键再次到达。

请求示意

请求示意
POST /v1/payments
Idempotency-Key: 7f3c9a52-1c4e-4b0a-9d33-3f6b0c9e21ab

# 首次请求:执行业务并记录结果
# 重复请求:直接返回首次处理结果与同一业务单号
# 键相同但参数不同:返回冲突错误,不执行新操作

基本信息

键的生成客户端生成(UUID 等),同一业务操作复用同一键
服务端处理唯一约束加结果缓存,注意缓存有效期
状态机不完整操作处于处理中时,重复请求应返回处理中而非再次执行
保留时长至少覆盖客户端的最大重试窗口

典型使用场景

  • 支付与退款:同一笔请求重试不能扣两次款
  • 下单接口:网络超时后客户端自动重试
  • 消息消费:至少一次投递语义下保证业务只生效一次
  • 开放平台接口:外部调用方无法保证不重发
  • 批量导入:重复上传同一文件应得到同一结果
幂等键必须与业务语义绑定:同一个键用于不同参数时应返回冲突,而不是执行新操作,否则会被用来绕过业务校验重复下单。

易错点

  • 客户端重试时重新生成键,幂等保护完全失效,重复写入照常发生
  • 缓存过期后同一键重新执行,出现重复业务动作
  • 只保存键不保存结果,重复请求返回空响应,调用方无法判断是否成功
  • 并发同键请求未加处理,两个线程同时通过存在性检查,双双执行业务

数据来源与参考

  • IETF 草案:The Idempotency-Key HTTP Header Field
  • Stripe API 文档:Idempotent requests
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌