微服务架构设计模式-(8)SAGA

saga(一种消息驱动的本地事务序列)

2PC

  • 参考:https://zhuanlan.zhihu.com/p/35616810
    • 协调者询问参与者是否可以正常执行
      • 参与者执行事务但不提交
    • 协调者根据结果发起通知(提交或回滚)
  • 缺点
    • 同步阻塞
      • 参与事务这个阶段,资源被锁住
    • 单点故障
      • 协调者故障,参与者阻塞
        • 特别是第二阶段的时候,大家都等着你发送消息呢
    • 数据不一致
      • 第二步的通知如果参与者没有收到,那么就会数据不一致
    • 无法解决的问题
      • 二阶段,协调者发出commit之后宕机,唯一接受到commit的机器宕机。那么就没人知道这个事务到底执行怎么样了。

3PC

  • 步骤
    • can commit
      • 协调者询问是否可以执行
    • pre commit
      • 协调者发送预执行
    • do commit
      • 协调者发送commit或中断
  • 与2PC的区别
    • 如果3阶段,参与者没有收到消息,超时之后,提交
    • can commit,不锁资源,减少可能的资源浪费

SAGA

  • 事务的执行分布在几个服务中
  • 串行执行
    • 三部分
      • 可补偿性事务
        • 它后面的事务失败,它需要回滚,但是它已经提交了,所以在后续任务失败时,它需要补偿。
          • 补偿方式之一:比如说订单创建,设置一个状态,表示订单状态。创建过程中,插入了一条新订单,其状态为creatting,但后续验证失败了,那么补偿性动作就是,将状态置为reject
            • 这种状态叫做语义锁。表示已经提交,但可能发生更改
            • 当然,事务的最后是需要把状态变成approve的。
      • 关键性事务
        • 后面跟着不可能失败的事务
          • 这个成功之后,后面的事务必定成功
      • 可重复性事务
        • 总是会成功。如果不成功,就重试,直到成功
          • 比如说把订单状态变成approve。只是修改一个字段的值嘛

协同式saga

  • saga的逻辑和执行顺序写入到参与的服务中
    • 假如执行顺序是A ->B -> C
      • A执行成功之后,发布消息
      • B接收到A的消息,执行
      • C接受到B的消息,执行
  • 好处
    • 简单
  • 问题
    • 可能存在循环依赖
    • 比较难以理解
      • 很难看到这个事务到底涉及哪几个服务
    • 紧耦合风险
      • B执行的这个事务,可能受到很多事件的影响,那么它要关注多个A的消息事件

编排式saga

  • 有一个编排器类,告诉参与方该做什么事情
  • 编排器建模好方法
    • 状态机
      • 一组状态和一组由事件触发的状态转化组成
  • 好处
    • 简单依赖关系
      • 不会引入循环依赖
      • 编排器依赖参与方
      • 参与方不依赖编排器
    • 较少的耦合
      • 参与方只提供服务API,不关心发布的事件
        • 就是我提供服务,你要用就来调我。我不关心你的情况(发布的事件)
    • 关注点隔离,简化业务逻辑
      • 参与者只需关系自己的业务
      • 编排器只需关注状态转换
  • 弊端
    • 编排器可能存在过多的业务逻辑
  • 问题
    • saga执行过程中,如果读取/修改数据,可能暴露数据不一致,怎么办?
      • 是事务隔离问题
      • 解决方法
        • 语义锁
          • 比如订单的创建状态
        • 合理安排执行顺序
        • 重读值
          • 作用:防止丢失更新
          • 做法:在更新之前,读取数据,验证是否做过修改
            • 读主库

猜你喜欢

转载自blog.csdn.net/u014704998/article/details/128879093