← 中文资源

简体中文版本

幂等性

幂等操作重复执行与执行一次产生相同的可观察结果,是分布式系统中安全重试的基础。

阅读英文原文

重试如何制造重复

客户端发送“创建订单”,服务端写入订单后连接在响应到达前断开,客户端重试。如果服务端无法识别这是重试,就会创建第二个订单。问题不在重试,而在缺少幂等契约。

两种常见实现

幂等键: 客户端生成唯一键并随请求发送;服务端把键与结果一起存储,重复键返回已存结果而不是重新执行。

天然幂等: 把操作表达为 upsert 或状态赋值,重复执行会收敛到同一状态:

INSERT INTO accounts (id, balance)
VALUES ($1, $2)
ON CONFLICT (id) DO UPDATE
SET balance = EXCLUDED.balance
RETURNING id, balance;

对相同输入,这个 upsert 是幂等的;而 balance = balance + 10 这样的相对更新不是。

键需要生命周期

幂等键应设置有限的保留期和唯一约束。需要决定重复请求在原始请求仍在处理中时如何处理:返回冲突、等待或重放原始响应。同时记录请求指纹,使同一键携带不同请求体时被拒绝,而不是静默返回无关结果。

何时使用

支付、订单创建、Webhook 处理、消息消费以及任何客户端可能自动重试的操作都需要幂等性。与 exactly-once 投递相比,幂等通常更便宜、更健壮:至少投递一次,并让处理逻辑可以安全重复。

陷阱

没有请求体校验的幂等键会掩盖客户端错误;没有过期时间的键会无限增长;把键当作授权令牌会造成安全漏洞。键是重试标识,不是身份或权限。

相关资源