幂等设计
让重试安全,使系统能自愈而不造重复。
为什么
网络失败、客户端重试,非幂等操作重试造重复——双扣、双发、双单。幂等(同输入 → 同结果,无论调几次)是让重试安全的性质,重试是让分布式系统可靠的。从头设计幂等(写幂等键、去重表、确定性 ID)花几小时;双扣事故后加花几周加诉讼。客户端可能重试的每个写都需幂等。
何时使用
每个写端点,上线前。每端点 1-2 小时。仅纯读端点可跳过。
如何做
1. 每写端点问:"客户端用同输入调两次会怎样?"
- 已幂等(PUT 固定 ID)→ 完成
- 不幂等(POST 每次建新行)→ 加幂等
2. 加 idempotency_key 参数(客户端生 UUID)
3. 写时查:见过此键吗?
- 是 → 返回存的结果(不重执行)
- 否 → 执行,存(键 → 结果)24 时 TTL
4. 内部事件用确定性 ID(如 "{order_id}-charged")使重投去重
5. 测:同请求发 3 次,断言恰一次副作用
6. 文档哪些端点幂等让客户端知重试安全示例
POST /v1/charges
body: { amount, customer_id, idempotency_key: "abc-123" }
首调:执行扣款,存(abc-123 → {charge_id: ch_1}),返 201
重试(网络抖):见 abc-123,返存 201 带 ch_1(无二次扣)
三调:同——返 ch_1
内部事件:order.charged 带 id "{order_id}-charged"
Kafka 重投 → 去重表拒 → 无双履约常见问题
- ⚠假设客户端不重试——会,尤其移动端;为之设计或接受重复。
最佳实践
- ✓所有非安全 POST 必填幂等键——缺键 400 比双扣好。
- ✓幂等记录与写同事务存,使其间崩溃不能造重复。