Saga 模式分布式事务:编排与协调器实现

FreeGuideOnline 最新 2026-06-16

Saga 模式分布式事务:从概念到实战

什么是分布式事务?为什么要用 Saga?

在微服务架构中,一个业务操作常常需要跨多个服务更新数据。例如,一个电商下单流程可能涉及订单服务、库存服务和支付服务。传统单数据库的事务(ACID)无法直接应用于这种跨服务场景。于是我们引入了分布式事务来保证数据一致性。

Saga 是一种为长时间运行、跨多个服务的业务事务提供最终一致性的解决方案。它把一个全局事务拆分为一系列有序的本地事务,每个本地事务都有对应的补偿操作。如果某个步骤失败,Saga 会反向执行已成功步骤的补偿操作,达到“回滚”的效果。

Saga 并非强一致性,而是最终一致性,中间会存在短暂的不一致窗口,适合对一致性实时性要求不极端、但必须保证最终数据对齐的业务场景。

Saga 的实现模式:编排与协调器

实现 Saga 主要分为两类:编排(Choreography)协调器(Orchestration)。选择哪种取决于团队规模、业务复杂度和对集中控制的需求。

编排(Choreography)

编排是一种去中心化的 Saga 实现。每个服务在完成自己的本地事务后,发布一个事件,其他服务订阅并响应。没有统一的指挥者,服务之间通过事件链自然衔接。

执行过程示例(下单流程)

  1. 订单服务创建订单,状态为PENDING,发布订单已创建事件。
  2. 库存服务接收事件,扣减库存,发布库存已扣减事件。
  3. 支付服务接收事件,执行扣款,发布支付已完成事件。
  4. 订单服务接收事件,将订单状态更新为已确认

失败回滚: 若支付失败,支付服务发布支付已失败事件。库存服务监听到后执行补偿(恢复库存),并发布库存已恢复事件。订单服务监听到后将订单置为已取消

优点

  • 简单易懂,适合小型系统。
  • 服务之间松耦合,容易扩展新步骤。

缺点

  • 流程散布在多个服务中,难以监控和排障。
  • 容易产生循环依赖或事件风暴。
  • 添加新步骤需要理解整个事件流,维护成本随复杂度上升。

协调器(Orchestration)

协调器模式引入一个中心化的 Saga 协调器(Orchestrator),它负责告诉每个参与者该执行什么本地事务,并处理失败补偿。协调器就像一个流程指挥家,按预定流程发送命令并接收响应。

执行过程示例

  1. 协调器发送创建订单命令给订单服务,订单服务返回成功。
  2. 协调器发送扣减库存命令给库存服务,库存服务返回成功。
  3. 协调器发送执行支付命令给支付服务,支付服务返回失败。
  4. 协调器按倒序发送补偿命令:向库存服务发送恢复库存,向订单服务发送取消订单

优点

  • 业务流程清晰集中在协调器中,易于理解、监控和修改。
  • 避免了服务间的依赖循环,减少耦合。
  • 适合复杂、多分支的业务流程。

缺点

  • 协调器可能成为单点瓶颈或性能热点(可借助异步、持久化等技术缓解)。
  • 服务之间仍需保证接口幂等性,且补偿逻辑需正确实现。

编排 vs. 协调器对比

维度 编排(Choreography) 协调器(Orchestration)
控制中心 无,事件驱动 有,集中式协调器
服务耦合 松(通过消息) 稍紧(需与协调器通信)
流程维护 较难,逻辑分散 集中,易于修改
测试与监控 复杂 简单,可单点跟踪
适用规模 小型、简单流程 中大型、复杂流程

Saga 协调器设计要点

如果你选择了协调器模式,设计时需关注以下核心问题:

1. 事务状态的持久化

协调器必须记录当前 Saga 的执行状态(如执行到第几步、每一步的成败)。状态通常存储在数据库中,避免协调器自身崩溃导致流程中断。通常采用事件溯源状态机模式保存。

2. 幂等性保证

参与者服务接收的命令或补偿可能因网络重试而重复到达。因此,每个服务接口都需要实现幂等性(比如通过唯一业务 ID 去重)。协调器也应具备重试机制,但需设定最大重试次数,超时后转为人工介入或特定补偿。

3. 补偿逻辑的正确性

补偿不是简单的“撤销”,它必须处理并发、中间状态和数据一致性。例如,扣减库存可补偿为加回库存,但如果加回时库存记录已被其他操作修改,则需要使用乐观锁或版本号防止覆盖。

4. 超时和异常处理

Saga 是长时间运行事务,参与方可能长时间无响应。协调器需对每个命令设置超时,超时后执行补偿或重试。同时需要处理协调器自身故障后的恢复:从持久化状态中恢复未完成的事务,继续执行或补偿。

5. 隔离性问题

Saga 缺乏传统事务的隔离性,可能在执行过程中其他事务读到中间状态。解决方案包括:

  • 语义锁定:在业务字段上增加状态标记(如PENDING),其他操作检查此标记。
  • 可补偿性分析:设计时确保补偿能正确处理脏读。
  • 假设失败率低:对于最终一致性能容忍短暂不一致的业务,不加锁。

亲手实现一个简单的 Saga 协调器

下面用伪代码展示一个基于状态机的协调器核心逻辑,帮助你理解实现模式。

class SagaOrchestrator:
    def __init__(self):
        # 假设有持久化存储 saga_state
        self.state_store = StateStore()

    def execute_saga(self, saga_id, saga_definition, input_data):
        # 初始化状态并持久化
        state = SagaState(saga_id, "STARTED", 0, input_data)
        self.state_store.save(state)
        try:
            for step in saga_definition.steps:
                # 发送命令并等待响应(可异步)
                response = self.send_command(step.service, step.command, input_data)
                if response.is_success():
                    state.current_step += 1
                    self.state_store.save(state)
                else:
                    # 步骤失败,开始补偿
                    self.compensate(saga_id, state.current_step)
                    return
            # 所有步骤成功
            state.status = "COMPLETED"
            self.state_store.save(state)
        except TimeoutError:
            self.compensate(saga_id, state.current_step)

    def compensate(self, saga_id, failed_step_index):
        state = self.state_store.get(saga_id)
        # 从当前步骤向前执行补偿
        for i in reversed(range(failed_step_index + 1)):
            step = saga_definition.steps[i]
            self.send_command(step.service, step.compensation_command, state.data)
        state.status = "COMPENSATED"
        self.state_store.save(state)

在实际项目中,你会使用消息队列、事件总线或 HTTP 调用来实现命令发送,并用数据库保存 sagas 状态。框架如 Axon Framework(Java)、EventuateMicroProfile LRA 或云服务(AWS Step Functions)都提供了现成的 Saga 支持。

Saga 模式落地的最佳实践

  • 明确定义边界:不是一个业务操作越长越适合 Saga,过长的事务考虑拆分为更小的流程。
  • 设计小步快跑的步骤:每个步骤应尽量短小、独立,避免跨服务长事务。
  • 优先使用协调器模式:对于大多数项目,协调器的可维护性优势远大于引入的集中点风险。
  • 实现全局唯一 ID:每个 Saga 实例有唯一 ID,并贯穿所有命令和事件,便于追踪。
  • 监控和告警:为 Saga 状态迁移设置监控,堆积的长时间未完成的 Saga 需要及时告警。
  • 从失败中恢复:提供管理接口手动重试或跳过某步,将人工干预作为兜底。
  • 与事件驱动的最终一致性结合:即使是协调器模式,最终通知也可以由事件完成,降低同步等待。

总结

Saga 模式是微服务架构中处理分布式事务的利器。它用一组有序的本地事务和补偿操作来保证业务数据的最终一致。两种实现风格——编排和协调器,分别适用于不同复杂度。协调器模式因其流程清晰、易于维护而成为大多数场景的首选。设计时,需要重点关注状态持久化、幂等性、补偿正确性和异常恢复。掌握 Saga 模式,你就能在微服务世界中游刃有余地设计可靠的数据一致性方案。