深入理解微服务下的 Saga 模式——以电商下单为例

在微服务架构中,一个业务流程往往跨越多个服务,每个服务都有独立数据库。传统单体事务 ACID 已经无法满足需求,这时 Saga 模式就派上用场了。

本文将结合我们深入讨论的内容,帮助你彻底理解 Saga 模式的本质、落地方式及常见误区。


1. Saga 模式概述

Saga 模式是一种 分布式事务管理模式,核心思想是:

  1. 将一个长事务拆解为多个小事务(Local Transaction)

  2. 每个小事务只在单个服务内部完成并保证本地 ACID

  3. 每个小事务都有对应的 补偿操作,用于回滚失败步骤,保证最终一致性

简单理解:Saga 关心"业务步骤是否成功",而不关心 CRUD 的内部实现。


1.1 Saga 小事务 VS CRUD

很多人容易混淆:

"Saga 小事务是不是微服务内部的增删改查操作?"

答案:不是。

  • CRUD :只是实现手段,例如订单服务里 INSERT order、库存服务里 UPDATE stock

  • Saga 小事务 :是业务流程中的独立步骤,例如"创建订单""扣减库存""扣款支付"

关键点

  • 小事务可以包含多个 CRUD 或 RPC 调用

  • Saga 只关注:这个步骤成功了没?失败了如何补偿?

📌 比喻:

  • CRUD = 手脚

  • Saga 小事务 = 踢球的动作

  • Saga 只关心"动作完成了没",不关心手指怎么动


2. Saga 小事务如何在微服务中执行

以电商下单流程为例,典型流程:

  1. 用户验证

  2. 创建订单

  3. 扣减库存

  4. 扣款支付

  5. 物流下单

每个步骤就是一个 Saga 小事务


2.1 如何拆分小事务

拆分原则:

  1. 每个小事务只涉及一个服务

  2. 每个小事务可以独立提交和补偿

Saga 小事务 属于服务 内部可能做的操作
用户验证 User Service 查用户是否存在、权限检查
创建订单 Order Service INSERT order、生成订单号
扣减库存 Inventory Service UPDATE stock、校验库存
支付扣款 Payment Service 扣款、写账务记录
物流下单 Shipping Service 创建发货单、调用物流 API

注意:小事务内部可以有多个 CRUD 或 RPC,但 Saga 只关心"这个步骤是否完成"。


3. 补偿机制详解

分布式事务无法用数据库级 rollback,因此 Saga 用 补偿机制

3.1 补偿逻辑

  • 补偿不是用户手动触发

  • 补偿逻辑必须由开发者编写

  • 执行顺序通常倒序,保证前面成功的步骤被撤销

举例:

  • 扣减库存失败

    • 订单服务:取消订单

    • 支付服务:返还余额

  • 物流创建失败

    • 支付服务:退款

    • 库存服务:回库存

    • 订单服务:取消订单


3.2 同步 Saga(Orchestrator 模式)

  • Orchestrator = 你自己写的总指挥函数

  • 顺序调用每个小事务

  • 失败立即触发补偿

示例(Go 伪代码):

复制代码
func PlaceOrderSaga(userId, productId string) error {
    err := userService.ValidateUser(userId)
    if err != nil { return err }

    err = orderService.CreateOrder(userId, productId)
    if err != nil { return err }

    err = inventoryService.DecreaseStock(productId)
    if err != nil {
        orderService.CancelOrder(userId, productId) // 补偿
        return err
    }

    err = paymentService.Debit(userId, productId)
    if err != nil {
        inventoryService.IncreaseStock(productId)
        orderService.CancelOrder(userId, productId)
        return err
    }

    err = shippingService.CreateShipment(userId, productId)
    if err != nil {
        paymentService.Refund(userId, productId)
        inventoryService.IncreaseStock(productId)
        orderService.CancelOrder(userId, productId)
        return err
    }

    return nil
}

特点

  • 中央 orchestrator 指挥整个流程

  • 失败立刻回滚

  • 补偿逻辑集中管理


3.3 异步 Saga(事件驱动 / Choreography 模式)

  • 每个事务完成后发事件,下一个事务监听事件执行

  • 失败时事务自己发失败事件

  • 补偿逻辑由事件处理器处理

流程示意:

复制代码
OrderCreated → InventoryReserve → Payment → Shipping
                 |
              失败事件
                 ↓
           补偿处理器回滚之前事务

关键区别

模式 谁发现失败 谁执行补偿
同步 Orchestrator Orchestrator
异步 失败事务自己 补偿事件处理器

4. 常见误区和实践建议

  1. 误区:Saga 小事务 = CRUD

    • 实际上 Saga 关注"业务步骤是否成功",CRUD 是内部实现
  2. Orchestrator 不是框架提供

    • 同步模式下,你需要自己写 Orchestrator

    • 异步模式下,补偿逻辑放在事件处理器里

  3. 补偿逻辑必须自己写

    • 不管同步还是异步

    • 同步写在 orchestrator 内

    • 异步写在事件处理器里

  4. 拆分小事务时要考虑补偿可行性

    • 一个小事务必须可回滚,否则整个 Saga 就不可用
  5. 同步 vs 异步

    • 同步:流程顺序明确、易理解,阻塞调用

    • 异步:服务解耦,系统可用性高,但流程复杂


5. 总结

  • Saga 小事务 = 业务流程步骤,不是 CRUD

  • Orchestrator = 流程总指挥,由开发者自己实现

  • 补偿逻辑由开发者编写,保证失败回滚

  • 同步 Saga:Orchestrator 按顺序执行

  • 异步 Saga:各服务异步发事件,补偿由事件驱动

  • Saga 适合 跨服务、长流程的分布式事务

Saga 模式的核心价值是:保证分布式系统一致性,同时保持高可用性和可伸缩性

相关推荐
菜萝卜子6 小时前
Kubernetes metrics-server 部署与全场景使用指南
云原生·容器·kubernetes
阿里云云原生7 小时前
祝贺东航首飞全球最长单程航线!通义千问和 AI 网关助力推出首个行程规划 Agent
云原生
腾讯云中间件8 小时前
Kafka 集群上云新突破:腾讯云 CKafka 联邦迁移方案
云原生·kafka·消息队列
腾讯云中间件8 小时前
腾讯云 RocketMQ 5.x:如何兼容 Remoting 全系列客户端
架构·消息队列·rocketmq
代码AI弗森8 小时前
构建超级个体:AI Agent核心架构与落地实践全景解析
人工智能·架构
檐下翻书1739 小时前
互联网企业组织结构图在线设计 扁平化架构模板
论文阅读·人工智能·信息可视化·架构·流程图·论文笔记
CinzWS9 小时前
基于Cortex-M3的PMU架构--关键设计点
架构·pmu
fanly119 小时前
创建抖音新号分享知识推广开源项目
微服务·surging microservice
白帽子黑客罗哥9 小时前
AI与零信任架构协同构建下一代智能防御体系
人工智能·架构