2. Saga 实现模式:Choreography(编排)模式详解、Orchestration(协同)模式详解、两种模式对比与选型
Saga 分布式事务的核心在于将长事务拆分为多个本地事务,并通过补偿机制保证最终一致性。根据决策与协调逻辑的分布方式,Saga 主要分为 Choreography(编排) 和 Orchestration(协同) 两种实现模式。理解两者的差异是设计高可用、可压测的 Saga 系统的前提。
2.1 Choreography(编排)模式详解
Choreography 模式是一种去中心化的架构。每个参与 Saga 的微服务在完成本地事务后,通过事件总线(如 Kafka、RabbitMQ)发布领域事件。其他服务监听这些事件,并根据事件内容决定执行下一步操作或触发补偿。
核心特征:无中心协调器,服务之间通过事件驱动进行“舞蹈式”协作。
2.1.1 工作流程
- 订单服务创建订单,发布“订单已创建”事件。
- 库存服务监听事件,扣减库存。若成功,发布“库存已扣减”事件;若失败,发布“库存扣减失败”事件。
- 支付服务监听“库存已扣减”事件,执行扣款。若成功,发布“支付已成功”事件;若失败,发布“支付失败”事件。
- 订单服务监听“支付失败”事件,触发补偿:将订单状态回滚为“已取消”,并发布“订单已取消”事件。
- 库存服务监听“订单已取消”事件,执行补偿:增加库存。
压测关注点:Choreography 模式对消息中间件的吞吐和延迟极为敏感。在压测场景库中,需要重点模拟事件积压、消息丢失、重复消费等场景,验证服务的幂等性和补偿的最终一致性。
2.2 Orchestration(协同)模式详解
Orchestration 模式引入一个中心化的 协调器(Orchestrator)。协调器负责管理整个 Saga 的执行流程,向各个参与服务发送指令,并根据执行结果决定下一步是继续还是触发补偿。
核心特征:有中心协调器,服务之间不直接通信,所有决策由协调器集中控制。
2.2.1 工作流程
- 协调器向订单服务发送“创建订单”指令。
- 订单服务执行成功,回复协调器。
- 协调器向库存服务发送“扣减库存”指令。
- 库存服务执行成功,回复协调器。
- 协调器向支付服务发送“执行支付”指令。
- 支付服务执行失败,回复协调器。
- 协调器根据失败结果,依次向库存服务发送“补偿扣减”指令,向订单服务发送“取消订单”指令。
压测关注点:协调器是单点瓶颈。压测时需要重点测试协调器的最大连接数、请求处理能力、状态持久化性能(如数据库写入TPS),以及协调器宕机后的恢复速度。
2.3 两种模式对比与选型
选择哪种模式取决于系统的复杂度、团队技术栈、以及对性能与一致性的要求。下表从多个关键维度进行对比:
| 对比维度 | Choreography(编排) | Orchestration(协同) |
|---|---|---|
| 架构风格 | 去中心化,点对点事件驱动 | 中心化,协调器统一调度 |
| 耦合度 | 服务间通过事件隐式耦合,事件结构变更影响面广 | 服务与协调器耦合,服务间解耦 |
| 复杂度 | 初期简单,但 Saga 流程越长,事件流越难追踪 | 初期需设计协调器,但流程可视化强,易于管理 |
| 性能瓶颈 | 消息中间件(吞吐、延迟) | 协调器(CPU、内存、DB 连接) |
| 容错与恢复 | 依赖消息重试和死信队列,补偿逻辑分散在各服务 | 协调器可持久化状态,支持断点续传和精确恢复 |
| 测试难度 | 需要模拟复杂的事件序列和时序问题 | 可对协调器进行单元测试和状态机模拟 |
| 典型应用 | 流程简单、服务数量少、团队对事件驱动熟悉 | 流程复杂、服务数量多、需要严格监控和治理 |
2.3.1 选型建议
- 优先选择 Choreography:当业务流程简单(2~3 个服务)、团队对事件驱动架构有成熟经验、且希望避免单点故障时。压测重点应放在消息中间件的集群性能和消息可靠性上。
- 优先选择 Orchestration:当业务流程复杂(超过 4 个服务)、需要严格的流程控制、审计日志、或需要支持复杂补偿逻辑(如条件分支、并行执行)时。压测重点应放在协调器的吞吐、状态持久化性能以及高可用切换上。
压测陷阱提示:在 Choreography 模式下,如果消息中间件出现性能抖动,会导致事件延迟,进而引发“超时补偿”与“正常流程”并发执行,造成数据不一致。在 Orchestration 模式下,如果协调器状态库出现锁冲突,会导致整个 Saga 链路阻塞。这两种场景必须在压测场景库中重点覆盖。