2. Saga 执行模型:Choreography 与 Orchestration 编排模式详解

Saga 事务的核心在于将一个分布式长事务拆解为一系列本地事务,并通过补偿机制保证最终一致性。根据事务协调逻辑的分布方式,Saga 主要分为两种执行模型:Choreography( choreography,编舞模式)和 Orchestration(编排模式)。理解这两种模式的差异,是设计高性能、高可靠 Saga 事务的基础。

2.1 Choreography 编排模式详解

Choreography 模式是一种去中心化的协调方式。每个参与 Saga 的微服务在完成本地事务后,会通过事件总线(如 Kafka、RabbitMQ)发布领域事件。其他服务监听这些事件,并根据事件内容决定是否执行下一步操作或触发补偿。

核心特征:无中心协调器,服务之间通过事件驱动进行点对点通信,形成事件链。

2.1.1 执行流程

  1. 服务 A 执行本地事务 T1,并发布事件 OrderCreated。
  2. 服务 B 监听 OrderCreated 事件,执行本地事务 T2(如扣减库存),并发布事件 InventoryDeducted。
  3. 服务 C 监听 InventoryDeducted 事件,执行本地事务 T3(如扣减余额),并发布事件 PaymentProcessed。
  4. 若 服务 C 执行失败,则发布 PaymentFailed 事件。
  5. 服务 B 监听 PaymentFailed 事件,执行补偿事务 C2(如恢复库存),并发布 InventoryRestored 事件。
  6. 服务 A 监听 InventoryRestored 事件,执行补偿事务 C1(如取消订单)。
适用场景:业务流程相对简单、服务数量较少(通常不超过 5 个)、团队对事件驱动架构有成熟经验的场景。

2.1.2 Choreography 模式架构图

下图展示了 Choreography 模式下,服务之间通过事件总线进行异步通信的典型流程。每个服务既是事件的发布者,也是事件的消费者。

Choreography 编排模式架构图 Choreography 模式:事件驱动去中心化协调 事件总线 (Event Bus / Kafka) 服务 A (订单服务) T1: 创建订单 C1: 取消订单 服务 B (库存服务) T2: 扣减库存 C2: 恢复库存 服务 C (支付服务) T3: 扣减余额 C3: 退款 补偿流程示例(服务 C 失败) 1. 服务 C 发布 PaymentFailed 事件 2. 服务 B 消费事件,执行 C2(恢复库存),发布 InventoryRestored 3. 服务 A 消费事件,执行 C1(取消订单)

2.2 Orchestration 编排模式详解

Orchestration 模式引入了一个中心化的协调器(Orchestrator)。该协调器负责管理整个 Saga 的执行流程,它向各个参与服务发送指令,并监听执行结果。协调器内部通常维护一个状态机,根据当前状态和收到的响应,决定下一步是执行正向事务还是触发补偿。

核心特征:有中心协调器,服务之间不直接通信,所有交互由协调器统一调度。

2.2.1 执行流程

  1. 协调器 向服务 A 发送执行 T1 的指令。
  2. 服务 A 执行 T1 并返回成功响应。
  3. 协调器 记录状态,向服务 B 发送执行 T2 的指令。
  4. 服务 B 执行 T2 并返回成功响应。
  5. 协调器 记录状态,向服务 C 发送执行 T3 的指令。
  6. 服务 C 执行 T3 失败,返回失败响应。
  7. 协调器 根据状态机,向服务 B 发送执行 C2 的补偿指令。
  8. 服务 B 执行 C2 并返回成功响应。
  9. 协调器 向服务 A 发送执行 C1 的补偿指令。
  10. 服务 A 执行 C1 并返回成功响应,Saga 结束。
适用场景:业务流程复杂、服务数量多(超过 5 个)、需要严格监控和审计、团队希望降低服务间耦合度的场景。

2.2.2 Orchestration 模式架构图

下图展示了 Orchestration 模式下,中心化协调器如何统一调度各个服务,并管理正向流程与补偿流程。

Orchestration 编排模式架构图 Orchestration 模式:中心化协调器调度 Saga Orchestrator 状态机 + 指令调度 服务 A (订单服务) T1 / C1 服务 B (库存服务) T2 / C2 服务 C (支付服务) T3 / C3 协调器状态机示例(服务 C 失败) 1. 状态: T1_DONE → 发送 T2 指令 → 状态: T2_DONE 2. 状态: T2_DONE → 发送 T3 指令 → 状态: T3_FAILED 3. 状态: T3_FAILED → 发送 C2 指令 → 发送 C1 指令 → 状态: SAGA_ABORTED

2.3 两种模式优缺点对比

选择哪种 Saga 执行模型,需要根据业务复杂度、团队技术栈、运维能力和性能要求综合判断。下表从多个关键维度对两种模式进行了详细对比。

对比维度 Choreography(编舞模式) Orchestration(编排模式)
协调方式 去中心化,事件驱动 中心化,指令驱动
服务耦合度 高(服务需感知其他服务的事件) 低(服务只与协调器交互)
业务流程复杂度 适合简单线性流程 适合复杂、分支、循环流程
可观测性 & 监控 困难(事件流分散在各服务日志中) 容易(协调器集中记录所有状态变更)
单点故障风险 无单点(但事件总线可能成为瓶颈) 有(协调器宕机影响全局)
性能开销 较低(异步事件,无中心瓶颈) 较高(协调器处理所有请求,存在网络和序列化开销)
调试 & 排错难度 高(需追踪跨服务的事件链) 低(从协调器日志即可定位问题)
事务补偿实现 隐式(通过事件链反向触发) 显式(协调器明确调用补偿接口)
典型实现框架 Eventuate Tram, Axon Framework Camunda, Temporal, 自研状态机
性能优化提示:在压测场景中,Orchestration 模式的协调器容易成为吞吐瓶颈。建议对协调器进行无状态化设计,并引入缓存(如 Redis)来存储 Saga 状态,减少数据库写入频率。Choreography 模式则需重点关注事件总线的分区数和消费者处理能力,避免事件堆积导致补偿延迟。

2.3.1 选型建议

  • 优先选择 Choreography:当业务流程是简单的线性链,服务数量少(≤5),团队对事件驱动架构有深入理解,且对端到端延迟不敏感时。
  • 优先选择 Orchestration:当业务流程包含条件分支、循环、超时重试等复杂逻辑,服务数量多(>5),需要严格的审计和监控,或者团队希望将事务逻辑与业务逻辑解耦时。
  • 混合模式:在大型系统中,可以针对不同子域采用不同模式。例如,核心交易链路使用 Orchestration 保证可靠性,非核心通知链路使用 Choreography 降低延迟。