1p3a-logo1p3a-logo
留学申请面试经验绿卡排期全民竞猜
    返回旧版通行证登录注册
首页
快讯
NEW
通知私信收藏阅帖历史积分中心
热门功能
🀄每日汉兜💼求职辅导🛍️跳蚤市场🏠租房找室友📱旧机回收比价
我的版块
我的标签

别再背幂等三板斧了:分布式系统真正危险的是这些边界条件digest-gif学习资料

秀眉丽眼的木耳
2026/8/5 · 发布于系统设计版·1292
--------------------------------------------------
一、请求还没处理完,重复请求撞进来怎么办?

核心冲突:处理中的状态与 Lease 机制

很多系统把幂等简化为“数据库唯一键 + 插入”,默认重复请求在前一个请求完全结束后到达。但实际中第二个请求常在第一个请求处于 In-Flight(处理中)时到达(例如等待第三方网关、慢 SQL)。

如果直接抛 Duplicate Key 并返回失败,客户端可能误认为没执行而重试;如果直接返回成功,而后端事务回滚,会造成“显示成功但未扣款”的资损。

常见工程范式
  • 服务端挂起/短轮询(Server Waiting/Polling):服务端内存或 Redis 等待前一个请求完成并复用结果(有 TTL)。
  • 明确告知客户端等候(Still Processing):返回特定状态码(如 202 或业务状态 STILL_PROCESSING),由客户端按指数退避查询。
处理权租约(Lease)与抢占
  • 租约占用:把 PROCESSING 视为对该 Identity 的临时占用,设置合理 lease(秒级或分钟级)。
  • 超时抢占:超时后,后续请求可通过带 lease 条件的 CAS(比较 lease_expire_at 或 version)获得处理权,接管执行。
--------------------------------------------------
二、系统怎么知道这是同一个请求?

核心冲突:请求身份(Identity)与 Token 误区

Token 是 Identity 的一种载体,但不能单独作为唯一状态源。
  • 先删 Token 再做业务:若 RPC 超时,用户重试时 Token 已删,导致误拦截或无法支付。
  • 先做业务再删 Token:并发请求在业务执行窗口内可能穿透,造成重复扣款。
在高价值交易中,Identity 应优先使用业务天然唯一边界(如 out_trade_no / biz_order_id)。Token 可作为辅助(例如 Stripe 的 Idempotency-Key),但不要把 Token 的删除视为业务状态迁移。

状态机的收敛链路
引入 Identity 后,必须用状态机管理其生命周期。UNKNOWN 不是终态,而是需要继续收敛的中间态。

INIT (原子性占位)
|
v
PROCESSING
/ | \
SUCCESS UNKNOWN FAILED
\ | /
(异步对账/查询收敛)
--------------------------------------------------
三、本地 DB 事务保不了远端 RPC

核心冲突:复杂网络下的状态收敛(Consistency)

外部 RPC 超时导致的状态倒置
常见错误做法:在本地事务内调用外部 RPC,并把超时当失败:
  • 开启本地事务,更新幂等表为 PROCESSING
  • 调用外部 RPC(网络 ACK 超时)
  • 抛异常,触发本地事务回滚
风险:外部 RPC 可能已实际执行(如已扣款),但本地幂等记录被回滚抹去。后续重试会被当作新请求再次调用 RPC,造成重复扣款。

推荐实践:优先持久化本地状态,异步对账收敛
  • 先落盘 PROCESSING:在发起 RPC 前,用独立事务将状态置为 PROCESSING 并提交,锁住并发入口。
  • RPC 超时时更新为 UNKNOWN,由后台对账或主动 Query 收敛为 SUCCESS 或 FAILED。
核心原则:幂等表是本服务范围内请求生命周期的事实来源(Source of Truth),后续重试/补偿/对账都围绕它进行状态迁移。

条件状态更新(CAS)
多线程竞争同一状态机时,必须使用带版本号或租约的条件更新,防止旧状态覆盖新状态。例如:

UPDATE idempotency_record
SET state = 'SUCCESS', response_body = '...', version = version + 1, updated_at = NOW()
WHERE identity_id = 'ORD_123456'
AND state = 'PROCESSING'
AND (lease_expire_at > NOW() OR owner_id = 'worker-node-01');
--------------------------------------------------
终局思考:Exactly-Once 究竟意味着什么?
物理层面纯粹的 Exactly-Once Delivery 在存在网络分区、重试和节点故障时不可实现。

Exactly Once Effect 依赖多要素收敛:
  • At-Least-Once Delivery(网络重试)
  • Unique Identity(精确识别)
  • Lease Ownership & State Machine(锁住并发与中间态)
  • Conditional Transition(防止状态倒置)
目标是 Exactly-Once Effect(业务结果恰好一次生效):不是消灭失败,而是在失败后仍能保证业务结果可控。
已获得 15 大米
avataravataravatar
+2
8
共0条回复

✨ 您正在体验新版论坛UI

👉 【有奖公测】反馈问题或建议

新手指南常见Q&A小黑屋关于我们加入团队联系客服VIP通行证购买鳄梨去广告企业招聘地里专栏商务洽谈服务条款社区守则隐私政策
youtubetwitter
1Point3Acres.com does not represent or guarantee the truthfulness, accuracy, or reliability of any of communications posted by users.
Copyright ©2009-2026 1Point3Acres.com All rights reserved. See Terms of Service.