关于 arch-saga
arch-saga 是讲解分布式业务流程中 Saga 模式的架构技能,适用于跨服务或涉及外部系统的多步骤事务。内容对比事件编排与集中编排,并强调通过幂等补偿实现最终一致性,而非回滚。
主要功能
- 01比较事件编排与集中编排
- 02说明补偿操作而非事务回滚
- 03强调步骤与补偿的幂等性
- 04建议持久化 Saga 状态
- 05提供模式选择与步骤排序准则
- 06列出常见反模式
适用场景
- 01设计跨多个服务的业务流程
- 02处理涉及支付等外部操作的步骤
- 03规划长时间运行且无法锁定的流程
- 04判断何时采用编排器或工作流引擎
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yonatankarp/ software-design-skills --skill arch-saga安装后在 Claude Code 中输入/arch-saga确认已加载。
详细介绍
一句话总结
将多步骤业务工作流作为一系列本地事务来执行,每个事务都属于各自的服务 / 聚合。如果某一步失败,则运行补偿操作,撤销之前已成功的步骤。这里没有回滚,只有向前执行的补偿。
何时使用此技能
- 业务流程跨越多个服务或多个聚合,无法共用单个事务。
- 某些步骤是外部操作(第三方 API、支付处理器),无法纳入事务。
- 长时间运行的工作流,持有分布式锁并不现实。
- 业务中有明确的概念:“如果步骤 X 失败,就运行步骤 X' 来撤销”。
何时不使用此技能
- 所有操作都发生在单个服务 / 单个聚合内——使用本地数据库事务。
- 各步骤具备幂等性且顺序无关——可能根本不需要 saga 协调。
- 确实需要“原子”回滚语义(在分布式系统中很少见)——saga 无法提供这种语义;它提供的是通过补偿实现的最终一致性。
核心内容
两种风格,协调方式各不相同:
编排式 saga。 每个服务监听事件,并决定何时执行操作。服务 A 完成步骤 1 并发出 Step1Completed;服务 B 接收该事件,完成步骤 2 并发出 Step2Completed;依此类推。补偿也通过事件发出(Step1Compensated)。
- 优点:去中心化,没有单点故障,可水平扩展。
- 缺点:完整工作流是隐式的——没有任何一方负责它;很难调试卡住的 saga;新增步骤需要修改多个服务。
编排器式 saga(流程管理器)。 中央编排器驱动工作流。它依次向各服务发送命令,监听它们的响应,并决定下一步操作(继续执行或补偿)。
- 优点:工作流是显式的,集中在一处,易于理解和测试。
- 缺点:编排器是一个必须具备高可用性的协调组件;集中化确实会带来成本。
执行补偿操作,而非回滚。
- 回滚(数据库事务)会将状态恢复到仿佛什么都没发生过。补偿操作则是撤销业务影响。退款属于补偿;如果付款已经完成,就不存在回滚付款这回事。
- 补偿必须具备幂等性,并且在部分完成后调用也必须安全。
- 有些操作无法补偿(已发送邮件、已调用不可逆的外部 API)。应将这些步骤安排在最后,这样 saga 更早失败时就不会执行到它们。
幂等性与至少一次投递。 Saga 运行在事件驱动的环境中。消息可能会重新投递。每个步骤和每项补偿都必须具备幂等性。
Saga 状态。 编排器(或者在编舞模式下,由多个服务分布式地)跟踪每个 saga 实例所处的位置。应持久化此状态——saga 可能会崩溃,因此必须能够恢复执行。
决策经验法则
- 步骤不超过 3 个且参与方稳定 → 采用编舞模式。
- 步骤达到 4 个或以上、可能在以后添加步骤,或补偿逻辑并不简单 → 采用编排模式。
- 安排步骤顺序,将不可逆步骤放在最后。
- 从一开始就为每个步骤实现幂等性。
- 持久化编排器状态;重启时重新加载。
- 当复杂度足以支持时,使用工作流引擎(Temporal、Camunda、Conductor),而不是自行构建编排器——但要审慎使用;它们是真正的依赖项。
反模式
- 名不副实的「Saga」:实际上是串联的同步 RPC。 服务 A 调用 B,B 再调用 C,中间没有事件代理。这是分布式调用链,不是 Saga;发生故障时不会执行补偿,只会向上传播。
- 补偿操作并非真正的补偿。 将记录标记为「已取消」,却没有向用户退款。这只撤销了一半。
- 步骤不具备幂等性。 同一条消息被重新投递 → 步骤运行两次 → 用户被扣费两次。
- 中间步骤不可逆。 步骤 3 发送了一封无法撤回的邮件;步骤 4~5 失败后,你无法撤回这封邮件。应将它放在最后。
- 包含 20 个步骤的 Saga。 这很可能应该用工作流引擎,而不是手动编写 Saga。
另请参阅
arch-event-driven— Saga 事件通过代理流转。arch-microservices— Saga 是「如何跨服务进行事务处理」的标准解决方案。arch-event-sourcing— Saga 状态通常通过事件溯源。arch-circuit-breaker— 调用其他服务的 Saga 步骤应做好保护。ddd-domain-event— Saga 步骤会生成/消费领域事件。
参考资料
- Hector Garcia-Molina 和 Kenneth Salem,《Sagas》(1987)— 原始论文。
- Khononov,《Learning DDD》,关于微服务/事件驱动章节中 Saga 的部分。
- Bellemare,《Building Event-Driven Microservices》,第 8 章(使用微服务构建工作流)。
评论
支持 Markdown