Saga 协同式实现

各服务订阅事件并在本地事务完成后发布新事件,由事件链推动流程;解耦度高、无中心组件,但整体流程分散,排障与变更影响评估更难。

Saga 协同式实现是什么

Saga 是分布式事务的补偿型方案:把长事务拆成一串本地事务,每个本地事务完成后发布事件,由订阅方触发下一步;失败时执行已成功步骤的补偿动作。协同式(choreography)指没有中心协调者,流程完全由事件链推动,各服务只订阅自己关心的事件。它的优点是松耦合、无中心组件;缺点同样明显:整体流程是隐式的,没有人从全局视角负责,排障需要按关联标识把事件拼起来,变更影响评估也更困难。

基本信息

结构事件链驱动,各服务订阅事件并决定后续动作
优势无中心编排组件,松耦合,易于增删参与者
风险流程隐式、缺少全局视图,容易出现循环与孤儿事件
补偿纪律补偿动作设重试上限,超限转人工处置队列
适用前提步骤少、参与者相对稳定、业务流程清晰可读

典型使用场景

  • 下单流程:订单、库存、支付、通知各服务通过事件串联,步骤较少
  • 账号开通:多个子系统依次初始化资源,失败时逐步回收
  • 内容审核:上传、转码、审核、发布各自发布事件,链式推进
  • 积分与权益发放:主流程成功后广播事件,各权益服务自行处理
  • 跨团队集成:各团队按事件契约自治,避免共享流程定义
  • 渐进式改造:先把同步调用改成事件链,降低一次性重构风险

协同式设计要点

事项做法说明
事件命名用过去时表达已发生的事实OrderCreated 而非 CreateOrder
订阅克制每个服务只订阅自己关心的少数事件订阅膨胀会让依赖关系不可控
关联追踪同一关联 ID 贯穿全链路事件与日志否则排障只能人工拼事件
消费防御幂等消费与乱序容忍一并设计至少一次投递是常态
流程文档维护事件流向图并随新增订阅同步更新隐式流程可见化是维持可维护性的前提

协同链路示意

协同链路示意
# 事件链:每一步都是本地事务 + 发布事件
OrderCreated      → 库存服务锁定库存 → StockLocked
StockLocked       → 支付服务发起扣款 → PaymentSucceeded
PaymentSucceeded  → 订单服务更新状态 → OrderConfirmed

# 失败路径(补偿链,逆序执行)
PaymentFailed     → 库存服务释放库存(幂等)→ StockReleased
# 每个事件都带 correlation_id,按它聚合链路即可还原流程实例
# 补偿动作要有重试上限,超过上限转人工队列并告警
协同式适合步骤少、参与者稳定的流程:步骤一多,事件链会变得难以理解,此时可对流程段局部引入编排器,把复杂度收进可管理的范围。
schema 治理不可省:事件字段变更按兼容规则管理(先加字段,消费方全部迁移后再清理),否则一次改动可能同时打断多个订阅方。

易错点

  • 事件链无全局负责方:异常路径长期无人处理,失败订单停留在中间状态
  • 缺少关联标识:问题定位需要人工拼接事件与日志,排障时间不可控
  • 事件循环触发:服务之间互相订阅造成无限放大,需要最大跳数与超时防护
  • 补偿动作不幂等:重试造成重复释放或重复退款
  • 新增订阅不更新流程文档:隐式依赖不断累积,变更影响无法评估

数据来源与参考

  • Chris Richardson《Microservices Patterns》
  • microservices.io 模式目录:Saga
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌