新闻详情

新闻详情

首页 / 资讯中心 / 详情

【基于 Swoole+Hyperf 的微服务实战】第八周·周一:分布式事务理论:CAP、BASE 与 Saga 模式设计

发布时间:2026/9/29 8:46:16来源:尧图网络
【基于 Swoole+Hyperf 的微服务实战】第八周·周一:分布式事务理论:CAP、BASE 与 Saga 模式设计
【基于 SwooleHyperf 的微服务实战】第八周·周一分布式事务理论CAP、BASE 与 Saga 模式设计今天我们进入第八周周一主题是分布式事务理论CAP、BASE 与 Saga 模式设计。经过前面七周的学习我们已经打通了微服务通信、治理、可观测性和异步消息但跨服务的数据一致性仍是一大挑战。今天我们将深入分布式事务的理论基石并设计一个基于 Saga 模式的订单流程为接下来两天的编码实战做好充分准备。今日目标理解分布式事务的核心难题掌握CAP 定理与BASE 理论的内涵及取舍。深入理解Saga 模式的两种实现方式编排式与协调器式并对比其优缺点。针对我们的电商场景设计一个完整的 Saga 订单流程图明确正向步骤和补偿操作。学习如何使用RabbitMQ 消息驱动实现 Saga 协调器并规划好消息体结构。输出一份Saga 设计文档为明天的编码实现奠定基础。一、环境与工具准备约 15 分钟今天不需要编写代码但需要准备好设计工具。绘图工具draw.io、ProcessOn 或任何流程图工具用于绘制 Saga 状态图。文档工具Markdown 编辑器用于编写设计文档。参考代码可以回顾第七周的订单消费者代码我们将在此基础上演进。启动 Docker 环境保持 RabbitMQ、MySQL 等运行我们可能需要查询表结构。docker-composeup-d二、知识核心CAP、BASE 与 Saga 模式约 2 小时1. 分布式事务的挑战在单体应用中我们可以依赖数据库的 ACID 事务来保证一致性。但在微服务架构中数据分布在不同的服务中每个服务有自己的数据库传统的本地事务无法跨服务。例如下单流程涉及订单服务创建订单库存服务扣减库存支付服务扣取款项这三个操作必须全部成功或全部失败。如果订单创建成功库存扣减失败整个业务就处于不一致状态。如何保证跨服务的原子性这就需要引入分布式事务。2. CAP 定理分布式系统的三个特性一致性Consistency所有节点在同一时刻看到相同的数据。可用性Availability每个请求都能得到非错误的响应但不保证数据最新。分区容错性Partition Tolerance系统在网络分区通信故障时仍能正常运行。CAP 定理指出一个分布式系统最多只能同时满足三项中的两项。由于网络分区不可避免P 必须满足因此我们必须在 C 和 A 之间做出取舍CP 系统当发生网络分区时牺牲可用性保证一致性如 Zookeeper、Consul 的强一致模式。AP 系统当发生网络分区时牺牲一致性保证可用性如 Eureka、Cassandra。对于大多数互联网业务可用性比强一致性更为重要因此通常会选择 AP 或 BASE 模型。3. BASE 理论BASE 是对 CAP 定理中 AP 的一种实践补充Basically Available基本可用系统在出现故障时允许损失部分可用性如响应时间变长、功能降级但不会完全不可用。Soft State软状态允许系统中的数据存在中间状态且该中间状态不会影响系统整体可用性。Eventually Consistent最终一致性系统中的所有数据副本经过一段时间的同步后最终能够达到一致状态而不是时时刻刻都保持强一致。在电商下单场景中BASE 理论体现为创建订单后库存扣减可以异步执行期间订单处于“处理中”状态几秒后最终要么扣减成功变为“待支付”要么扣减失败变为“已取消”。这种短暂的不一致是可以接受的。4. Saga 模式Saga 是实现 BASE 理论最常用的分布式事务模式之一由 Hector Garcia-Molina 在 1987 年提出。核心思想将一个长事务拆分为多个本地事务每个本地事务都有对应的补偿操作。如果任何一个本地事务失败Saga 会按相反顺序调用补偿操作从而保证最终一致性。实现方式编排式Choreography无中心协调器每个服务订阅事件并执行自己的事务完成后发布下一个事件。好处是低耦合缺点是流程分散难以追踪。协调器式Orchestration由一个 Saga 协调器Orchestrator集中控制整个流程向各个服务发送命令并监听回复。优点是流程清晰可控缺点是协调器成为单点。在我们的课程中我们将采用协调器式用 RabbitMQ 作为命令通道实现一个高可用的协调器。5. Saga 的补偿与隔离性问题补偿操作必须是幂等的并且能够正确处理业务逻辑的逆操作如恢复库存、取消订单。补偿也可能失败需要重试机制。隔离性问题Saga 是 ACD原子性、一致性、持久性而非全 ACID缺少隔离性。会出现脏读、不可重复读等问题。解决方案有语义锁在订单处理期间对商品库存进行预扣冻结其他订单无法冻结该库存。版本号更新时检查版本号防止覆盖。我们今天的设计将采用“预扣库存”方式保证隔离性。三、实战设计下单 Saga 流程图与补偿操作约 2.5 小时步骤 1定义参与方和本地事务我们简化为三个服务但实际上今天在一个项目内模拟订单服务创建订单、取消订单库存服务冻结库存、解冻库存支付服务扣款、退款正向流程订单服务创建订单状态 PENDING库存服务冻结库存预扣减防止超卖支付服务执行扣款订单服务更新订单状态为 PAID补偿流程逆向若支付失败步骤3则需要补偿支付无因为未扣款解冻库存步骤2补偿取消订单步骤1补偿若冻结库存失败步骤2则需要取消订单步骤1补偿步骤 2绘制 Saga 状态图使用工具画出如下流程文字描述[启动] → 创建订单 → [成功] → 冻结库存 → [成功] → 执行扣款 → [成功] → 确认订单 (END) ↓ 失败 ↓ 失败 ↓ 失败 (结束) 取消订单 退款 解冻库存 取消订单每个箭头上的“失败”代表该本地事务执行失败或超时Saga 协调器会触发补偿链。步骤 3设计协调器消息交互我们使用 RabbitMQ 的direct交换机命令和回复采用不同队列。命令通道协调器发送命令到各服务队列。order.command.create→ 订单服务inventory.command.freeze→ 库存服务payment.command.debit→ 支付服务回复通道各服务处理完业务后将结果成功/失败发送回协调器专用队列。saga.reply协调器监听此队列。消息体格式JSON{saga_id:uuid,action:create_order,payload:{order_id:1,user_id:1,amount:99.00,product_id:1},status:success|failed,error:optional error message}协调器维护一个状态机根据当前步骤和回复结果决定下一步动作。步骤 4设计 Saga 数据库表协调器状态持久化为确保协调器在重启后能恢复 Saga 状态需要将状态持久化到 MySQL。创建表saga_transactionsCREATETABLEsaga_transactions(idINTAUTO_INCREMENTPRIMARYKEY,saga_idVARCHAR(64)NOTNULLUNIQUE,statusENUM(running,completed,compensating,failed)NOTNULLDEFAULTrunning,current_stepVARCHAR(50)NOTNULL,payload JSONNOTNULL,created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,updated_atTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP);每一步执行后更新current_step和payload协调器重启时可加载未完成的 Saga 继续执行。步骤 5编写 Saga 设计文档今天需要产出一份 Markdown 文档docs/saga-design.md内容至少包括业务场景下单流程。CAP/BASE 选择BASE最终一致性可用性优先。Saga 模式选择协调器式原因流程清晰便于追踪和重试。参与方与 API订单服务、库存服务、支付服务的命令接口。正向步骤与补偿映射表步骤操作成功后续失败补偿1创建订单 (order.create)冻结库存取消订单 (order.cancel)2冻结库存 (inventory.freeze)执行扣款解冻库存 (inventory.unfreeze) 取消订单3执行扣款 (payment.debit)确认订单退款 (payment.refund) 解冻库存 取消订单4确认订单 (order.confirm)结束-消息队列拓扑交换机名称、命令队列、回复队列、死信队列。状态机图使用 Mermaid 语法或图片。异常处理超时机制、重试策略、人工干预入口。四、成果测试与验证约 1 小时今天的“测试”主要是设计评审和模型验证。1. 设计评审检查清单是否有明确的业务边界各服务的本地事务是否隔离补偿操作是否幂等例如“取消订单”多次调用是否安全如何处理网络超时是否需要“查询模式”确认状态协调器本身是否高可用状态持久化是否可靠死信队列是否已规划用于处理补偿失败的情况Saga 状态图是否可以处理并发下单通过语义锁2. 模拟场景走查在纸上或脑中模拟以下场景场景1成功一切顺利订单从 PENDING → FROZEN → PAID。场景2库存不足冻结库存失败协调器收到失败回复调用取消订单。订单状态变为 CANCELLED。场景3支付超时支付服务长时间不回复协调器超时后启动补偿先查支付状态若未扣款则退款然后解冻库存取消订单。场景4补偿失败取消订单时订单服务宕机协调器重试 3 次后转入死信人工介入。3. 预期产出Saga 设计文档Markdown 格式状态图截图或 Mermaid 代码块消息拓扑图将以上产出提交到项目的docs/目录。五、今日作业与学习产出提交设计文档将saga-design.md提交到 Git。完善设计考虑如何实现“空回滚”即创建订单失败却收到补偿请求需要忽略。设计一个简单的“幂等性”方案确保命令重复发送不会导致重复操作使用 Redis 或数据库唯一索引。学习笔记用自己的语言解释 CAP 定理并举出两个常见中间件的 CP/AP 选择。总结 Saga 编排式和协调器式的适用场景为什么在微服务中协调器式更为常见挑战任务研究TCC (Try-Confirm-Cancel)模式对比 Saga思考在“扣款”场景下哪种更合适。了解Seata框架的 AT 模式思考为什么 PHP 生态没有类似的成熟框架我们如何用协程实现类似的自动补偿通过今天的学习你已经从理论上掌握了分布式事务的核心知识并拥有了一个切实可行的 Saga 设计蓝图。明天我们将亲手编写 Saga 协调器让这张蓝图在代码中活起来
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SSD当显存跑744B大模型:原理、性能与调优实战 2026/9/29 9:37:01

SSD当显存跑744B大模型:原理、性能与调优实战

在本地显存有限的前提下强行跑 744B 这种参数量的大模型,听起来像是拿自行车去跑高速。但 GitHub 上最近传得很热的“蜂鸟”项目,核心思路确实有点反常识:它不靠显存,靠 SSD 当“慢速显存”来顶住推理压力。我自己在笔记本上照着重…

阅读更多 →
TRAE Work驱动的公众号日更流水线:从2小时到15分钟 2026/9/29 9:37:01

TRAE Work驱动的公众号日更流水线:从2小时到15分钟

上个月某个周六下午,我坐在电脑前整整四个小时,只干了一件事:把当天公众号要发的那篇稿子,从一堆零散想法变成能点发布的排版稿。中途我换了不下二十次窗口,在素材文件夹、浏览器标签、编辑器预览之间来回横跳&#xf…

阅读更多 →
DeepSeek政务政策问答系统实战:从数据清洗到API部署 2026/9/29 9:37:01

DeepSeek政务政策问答系统实战:从数据清洗到API部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
2024年TensorFlow实战指南:从安装到部署的踩坑经验 2026/9/29 9:36:54

2024年TensorFlow实战指南:从安装到部署的踩坑经验

TensorFlow 这个名字,估计只要碰过深度学习的朋友都绕不开。2024 年再聊它,比前几年有意思多了:一边是 PyTorch 在论文复现、学术社区里几乎成了默认选项,另一边是 TensorFlow 在工业落地、移动端推理、服务端部署这些场景里依然有…

阅读更多 →
AI编程Skills实战指南:从安装到编写,打造Agent能力封装 2026/9/29 9:36:54

AI编程Skills实战指南:从安装到编写,打造Agent能力封装

最近 AI 编程圈子里好几个群里都在刷一个词:skills。Claude Code 的 skills、Codex 的 skills、OpenCode 也来凑热闹,连华为杯、数学建模的比赛群里都有人问“有没有好用的 skills 推荐”。粗看像是某个新插件,其实它是 Agent 时代的一种“能…

阅读更多 →
AI编程助手Skills完全指南:从概念到安装、编写与维护 2026/9/29 9:36:53

AI编程助手Skills完全指南:从概念到安装、编写与维护

1. Skills 到底是什么:一次搞懂这轮新玩法的底层逻辑最近半年,AI 编程助手圈子里最让我觉得值得花时间研究的概念,就是 skills。我最早是在 Claude Code 里接触到的,当时团队里一个同事把代码评审的规范做成了一个技能包&#xff…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉