这里写自定义目录标题

  • Sagas
  • Sagas 的实现范式


Sagas

每个Sagas由一系列sub-transaction Ti (saga)组成
每个Ti 都有对应的补偿动作Ci,补偿动作用于撤销Ti造成的结果
可以看到,和TCC相比,Saga没有“预提交”阶段,它的Ti就是直接提交到库。

  • Sagas两种可能的执行流程
  1. T1, T2, T3, …, Tn
  2. T1, T2, …, Ti, Ci,…, C2, C1,其中0 < i < n
  • Sagas的 恢复策略
  1. backward recovery,向后恢复,补偿所有已完成的事务,如果任一子事务失败。即上面提到的第二种执行顺序,其中j是发生错误的sub-transaction,这种做法的效果是撤销掉之前所有成功的sub-transation,使得整个Sagas的执行结果撤销。
  2. forward recovery,向前恢复,重试失败的事务,假设每个子事务最终都会成功。适用于必须要成功的场景,执行顺序是类似于这样的:T1, T2, …, Tj(失败), Tj(重试),…, Tn,其中j是发生错误的sub-transaction。该情况下不需要Ci。
  • Sagas的使用注意事项
  1. 只允许两层嵌套,整个事务我们叫主事务(Sagas)和子事务Saga,子事务(saga)是互相独立的原子操作。
  2. Sagas不保证ACID,只保证最终一致性。即Ci必须保证成功,即使系统不能成功也需要人工干预,这种情况下需要saga log支持。
  3. 基于上面,整个Sagas事务无原子性特征,即一个Sagas可以看到另外一个Sagas的中间状态,即部分结果
  4. Ti、Ci需要幂等,且先后执行Ti、Ci即使顺序不同也能保证结果一致,即事务被撤销
  5. 补充事务Ci从语义上撤销了Ti的影响,但不一定能让系统/数据库回到原先的状态。例如Ti将邮件发送出去了,Ti发射了鱼雷。这里需要特别注意
  • Sagas的优缺点和使用场景
    由于saga直接提交事务而没有TCC的Try的阶段,所以减少了一次通信成本,效率更高,但对于复杂的事务,提供补充机制的成本可能很高,同样没有预提交也没有资源释放及异常处理的问题,这点和TCC相比算是各有优势;另外对于长事务,即i值较大时,回退的流程可能很长,性能和效率会有较大影响;最后,没有预提交阶段,存证上节提到的Ci无法保证系统的整体状态回到Ti发生前。
    基于此的场景:
  1. 较简单的业务,提供补充Ci较简单
  2. 系统集成,其中遗留子系统或第三方服务无法提供预提交(Try)能力的情况,只需要增加补偿机制即可实现

Sagas 的实现范式

下面以一个电商系统为例,该案例中Saga的实现层,基于一个可持久化且可靠的消息系统实现

  • ** 基于编排模式(Choreography)**

微服务降级策略有哪些 微服务saga_Customer



  • 基于编排的Sagas创建订单,包含以下步骤:
  1. 在Order Service接收到该POST /orders请求并创建一个PENDING状态的Order
  2. 然后发出一个Order Created事件
  3. Customer Service的事件处理程序尝试扣减信用(信用卡消费)
  4. 然后Customer Service发出一个指示结果的事件
  5. OrderService的事件处理程序完成或拒绝Order
  • ** 基于编制模式(Orchestration)**

微服务降级策略有哪些 微服务saga_执行顺序_02



  • 基于编制的Sagas创建订单,包含以下步骤:
  1. 在Order Service接收到该POST /orders请求并创建Create Order Sagas协调器(orchestrator,可看作一个编制的api,后续介绍服务编排会再提到
  2. Sagas协调器创建一个PENDING状态的Order
  3. 然后,它发送Reserve Credit命令到Customer Service
  4. Customer Service尝试扣减信用
  5. 然后,Customer Service发送回包含结果的回复消息
  6. Sagas协调器完成或拒绝 Order