zoukankan      html  css  js  c++  java
  • 分布式事务参考

    原先的单机系统,所有的逻辑都在同一台机子、同一个运行环境中,事务的提交相对比较简单。

    而在微服务的架构中,由于不同的服务层(或能力层)被分开,虽然公开的都是API接口,但是由于服务已经被拆分部署,实际上事务已经无法简单在单机中提交和回滚了。

    1、理论阶段

      1.1、二阶段提交(2PC)

        第一阶段(Prepare)

          1、协调者(事务管理TM)记录日志并向所有参与者(RM)发送准备提交信息

          2、参与者收到信息后,记录日志;返回就绪或撤销信息

          3、协调者如果在规定的时间内收到所有参与者的就绪信息,就做出提交的决定;否则做出撤销的决定

        第二阶段 执行阶段(Commit/Rollback)

          1、协调者先将决定记录到日志,然后把这个决定发送给所有的参与者

          2、参与者收到命令后先记录日志,并向协调者发送应答消息,然后执行决定的命令

          3、协调者收到应答消息后,则事务结束。有关日志可以自行决定如何存储

      1.2、三阶段提交(3PC)

        第一阶段(Prepare):

          1、协调者(事务管理TM)向所有参与者(RM)发出准备信息

          2、若任一参与者返回Abort,则执行第三阶段,Rollback

          3、若所有参与者返回vote-commit,则进入第二阶段

        第二阶段(Prepare To Commit)

          1、协调者(事务管理TM)向所有参与者(RM)发送准备提交信息

          2、参与者收到信息后,记录日志,并回复确认消息ACK

        第三阶段 执行阶段(Commit/Rollback)

          1、协调者根据第一阶段回复的Abort执行Rollback或者根据第二阶段回复的ACK消息向参与者发送Commit或Rollback

          2、参与者根据协调者发送的信息决定执行Commit或Rollback操作

       

      重点:

    • 参考mysql innoDB的redo和undo日志的二阶段提交,日志利用了命令模式的do 和 undo,即命令的执行和回滚
    • 2PC和3PC都存在锁定资源的情况,只是3PC锁定的时间会更短些
    • 2PC和3PC都存在事务最终失败,需要回滚或补偿的情况(指的并非正常收到通知之后做出的Rollback决策,而是指服务突然宕机造成的A服务执行成功,B服务宕机,造成事务失败的情况),只不过这种情况相对几率较小;一般的系统采用2PC或3PC即可

       1.3、本地事件表

        简单来说是基于事件驱动的,可以这么来理解吧,比如订单模块已经完成提交并实际支付成功,假设这时候是通过订单模块调用到支付模块的确认支付成功。

        那么大致的流程可以是这样:

          1)订单模块实际调起支付并支付成功

          2)第三方支付回调订单模块接口,订单模块接口插入 支付成功事件  到本地事件表

          3)定时器轮询查出对应的支付成功事件,设置为已发送,并发送到消息中间件

          4)支付模块通过监听支付成功事件的队列,插入本地事件表(注意:此处事件表可以是自己服务本地的数据库)

          5)定时器轮询处理本地事件表(或者也可以在4)中直接处理)

        本地事件表主要是为了解耦,也是为了速度和稳定性,比如说一个注册事件可能触发发送短信或者赠送积分的事件,此时通过最简短的数据本地持久化事件是最快且稳定的;之后再通过定时器轮询执行

        这边的消息中间件也只是用于传递不同服务之间的信息。

        这种模型比较适用系统的数据量不会太大,且一般要求最终所有事务都要提交成功的场景。

      demo activemq参考

    2、LCN框架实战(详细叙述

    3、Seata(详细叙述

    4、可靠性消息服务->最终一致性:这个模式算是本地事件表的升级版,升级体现在优化了消息队列的扩展性,自身实现了一个可靠性消息服务(将本地事件表统一到中台服务中)

    5、本地业务+事务性消息队列:本地业务执行完自身的逻辑(通常比较简单),直接怼到事务性消息队列(严格意义上讲,是在执行本地业务逻辑的时候先预提交一个消息;成功后确认消息,失败后撤销消息)。

    这个模式是可靠性消息服务的升级版,直接集成其功能到消息中间件中。(RocketMq)

    Demo 待补

    6、最大努力通知:参考微信支付的通知模式,25小时内通知8次,逐次增加通知的间隔;超过就不管了

    ps:LCN、Seata At模式简单,侵入性低,但性能比较差,At已经在LCN的基础上再次优化,但由于较强的一致性要求,导致性能方面会受到影响

  • 相关阅读:
    MyBatis的动态SQL详解
    Mybatis实现Mapper动态代理方式
    解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variable and mvn script match.
    springmvc前台向后台传值几种方式从简单到复杂
    Maven 项目无法在Ecplise加进tomcat server
    解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variable and mvn script match.
    tomcat启动startup.bat一闪而过
    用Eclipse创建一个Maven Web项目
    使用Yeoman搭建 AngularJS 应用 (8) —— 让我们搭建一个网页应用
    使用Yeoman搭建 AngularJS 应用 (7) —— 让我们搭建一个网页应用
  • 原文地址:https://www.cnblogs.com/gabin/p/13765442.html
Copyright © 2011-2022 走看看