美文网首页GO与微服务
手撸golang GO与微服务 Saga模式之9 小结/gite

手撸golang GO与微服务 Saga模式之9 小结/gite

作者: 老罗话编程 | 来源:发表于2021-03-19 11:35 被阅读0次

    手撸golang GO与微服务 Saga模式之9 小结/gitee源码

    缘起

    最近阅读<<Go微服务实战>> (刘金亮, 2021.1)
    本系列笔记拟采用golang练习之

    Saga模式

    • saga模式将分布式长事务切分为一系列独立短事务
    • 每个短事务是可通过补偿动作进行撤销的
    • 事务动作和补动作偿都是幂等的, 允许重复执行而不会有副作用
    Saga由一系列的子事务“Ti”组成,
    每个Ti都有对应的补偿“Ci”,
    当Ti出现问题时Ci用于处理Ti执行带来的问题。
    
    可以通过下面的两个公式理解Saga模式。
    T = T1 T2 … Tn
    T = TCT
    
    Saga模式的核心理念是避免使用长期持有锁(如14.2.2节介绍的两阶段提交)的长事务,
    而应该将事务切分为一组按序依次提交的短事务,
    Saga模式满足ACD(原子性、一致性、持久性)特征。
    
    摘自 <<Go微服务实战>> 刘金亮, 2021.1
    

    目标

    • 为实现saga模式的分布式事务, 先撸一个pub/sub事务消息队列服务
    • 事务消息队列服务的功能性要求
      • 消息不会丢失: 消息的持久化
      • 消息的唯一性: 要求每个消息有全局ID和子事务ID
      • 确保投递成功: 投递队列持久化, 投递状态持久化, 失败重试

    Saga模式小结:

    1. 写一个Saga模式的小demo, 居然累计投入20工时左右的码力, 看来分布式事务确实是个大麻烦
    2. Saga模式虽然区区两个公式, 但手撸一遍, 深刻理解后, 才发现后面很多道道
    3. 首先看看事务拆分: T = T1 T2...Tn
      1. 首先如何拆分事务就非常讲究
      2. 其次必须确保每个事务的原子性和幂等性, 不能产生副作用. 这要求很高, 事实上几乎只能选择RDBMS的本地事务
      3. 复杂逻辑处理遇上原子性, 则很可能需要持久化很多中间状态, 因为云环境下, 必须假设Pod随时可能挂掉. 这就好比在战棋类游戏中, 走一步存一个挡.
    4. 再看看补偿机制: T = TCT
      1. 首先事务必须是可撤销/可补偿的. 但有些场景很难撤销/完全补偿
      2. 比如电商大促, 消费者买买买
      3. 如果店小二填入库单的时候, 不小心输多一个0, 库存暴涨
      4. 则可能导致大量蜂拥而至的消费者, 产生大量销售订单.
      5. 如果有禁止负数库存的硬约束, 想要撤销入库单是很难的
      6. 必须先撤销大量的销售订单, 这个实施成本很高.
    5. 其他技术难点:
      1. 事务消息队列服务MQS本身的单点故障: 这个可以做主从HA+消费端保活+消费端自动失败重试
      2. 事务消息的100%可达性: 持久化+消费应答机制
      3. 事务消息的可重复消费/幂等: 事务ID+已消费记录的持久化, 这个要在消费端做, 服务端不能100%避免
      4. 生产者早于消费者上线: 消费端还没上线订阅, 生产者就已经Pub大量消息. 这个要有时序控制机制.
      5. 慢消费者: 某个消费端因负载过高, 通信很慢, 比起其他消费端总是慢吞吞, 则最终一致性要很久才能达成.
      6. MQS的过载保护: 需要实时采集和监测, 发布队列与消费队列的深度

    gitee源码

    [手撸golang]系列博文涉及的golang源码已完整上传gitee仓库:
    https://gitee.com/ioly/learning.gooop
    有需要的童鞋请随意

    (saga系列end)

    相关文章

      网友评论

        本文标题:手撸golang GO与微服务 Saga模式之9 小结/gite

        本文链接:https://www.haomeiwen.com/subject/dtsvcltx.html