zoukankan      html  css  js  c++  java
  • [分布式] 分布式事务、seata

    资料

    文章

    质量不错, 以这篇文章为主, 其他的为辅;
    再有人问你分布式事务,把这篇扔给他

    思路清晰, 语言简洁;
    分布式事务,这一篇就够了 | 小米信息部技术团队

    似乎更全面;
    分布式事务最经典的七种解决方案 - SegmentFault 思否

    alibaba/seata

    资料

    seata/seata: Seata is an easy-to-use, high-performance, open source distributed transaction solution.

    示例代码:
    https://github.com/seata/seata-samples

    spring-cloud快速集成
    seata-samples/quick-integration-with-spring-cloud.md at master · seata/seata-samples

    配置

    service.vgroupMapping 事务分组

    Seata 参数配置
    file.conf:

    service {
      #transaction service group mapping
      vgroupMapping.my_test_tx_group = "default"
    

    service.vgroupMapping.my_test_tx_group 事务群组(附录1) my_test_tx_group为分组,配置项值为TC集群名

    事务分组说明
    1.事务分组是什么?
    事务分组是seata的资源逻辑,类似于服务实例。在file.conf中的my_test_tx_group就是一个事务分组。
    2.通过事务分组如何找到后端集群?
    首先程序中配置了事务分组(GlobalTransactionScanner 构造方法的txServiceGroup参数),程序会通过用户配置的配置中心去寻找service.vgroupMapping.事务分组配置项,取得配置项的值就是TC集群的名称。拿到集群名称程序通过一定的前后缀+集群名称去构造服务名,各配置中心的服务名实现不同。拿到服务名去相应的注册中心去拉取相应服务名的服务列表,获得后端真实的TC服务列表。
    3.为什么这么设计,不直接取服务名?
    这里多了一层获取事务分组到映射集群的配置。这样设计后,事务分组可以作为资源的逻辑隔离单位,当发生故障时可以快速failover。

    上手: springcloud-jpa-seata

    Quick Start

    https://github.com/seata/seata-samples/tree/master/springcloud-jpa-seata

    我的测试代码:
    https://github.com/qiaoxingxing/seata-samples/tree/qxx

    seata服务端docker安装

    docker run --name seata-server -p 8091:8091 -p 9091:9091 seataio/seata-server:latest
    

    localhost:9091/health返回ok;

    seataio/seata-server - Docker Image | Docker Hub

    seata/Dockerfile at 17b05038870e34318e82b1eabec700c1c48cfc85 · seata/seata

    mysql安装

    Mysql - Official Image | Docker Hub

    docker run --name mysql_local 
     -e MYSQL_ROOT_PASSWORD=root123456 
     -e MYSQL_PASSWORD=root123456 
     -p 23306:3306 
      harbor.sjgs/library/mysql:5.7.30
    

    示例代码: springcloud-jpa-seata

    https://github.com/seata/seata-samples/tree/master/springcloud-jpa-seata
    参考readme.md;
    代码修改:

    • 数据库地址
    • 所有application.properties增加spring.cloud.alibaba.seata.txServiceGroup=my_test_tx_group
    • java8启动

    Q&A


    报错:
    io.seata.common.exception.FrameworkException: No available service
    事务分组配置问题;
    方法1: 所有application.properties增加spring.cloud.alibaba.seata.txServiceGroup=my_test_tx_group

    方法2:
    所有服务改造为对应的值${spring.application.name}-fescar-service-group:

    service {
      #transaction service group mapping
      vgroupMapping.business-service-fescar-service-group = "default"
    

    感想: 文档里说service.vgroupMapping配置要"一致", 但是怎样才算是一致? 我以为是一模一样; 好的文档应该提供一个例子, 不然根本不知道他具体在说什么;


    启动报错:
    Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
    jdk 1.8启动
    java - Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer] - Stack Overflow

    分布式事务和数据一致性

    imooc笔记: 第16周.分布式全局ID、分布式事务和数据一致性;

    理论

    CAP原理

    C - Consistent , 一致性。 操作成功以后, 所有的节点在同一时间看到的数据都是完全一致的。
    A - Availability, 可用性。 指服务一致可用, 在规定的时间内完成响应。
    P - Partition tolerance , 分区容错性。 指分布式系统在遇到某节点或网络分区故障的时候, 仍然能够对外提供服务。也就是: 一个节点出错, 其他节点可以提供服务;
    CAP原理指出, 这3个指标不能同时满足, 最多只能满足其中的两个。
    简单理解: 分布式服务一般需要P(一个节点出错, 其他节点可以提供服务), 否则分布式没有意义; 如果要保证C, 节点间同步数据的间隙不能提供服务, 违背了A; 如果要保证A, 节点同步数据的间隙数据是不同的, 违背了C.

    ACID原理

    A - Atomicity(原子性) , 事务中的操作要么都做, 要么都不做。
    C - Consistency(一致性) , 系统必须始终处在强一致状态下。
    I - Isolation(隔离性) , 一个事务的执行不能被其他事务所干扰。
    D - Durability(持久性) , 一个已提交的事务对数据库中数据的改变是永久性的。
    ACID强调的是强一致性, CAP原理中, 保证的是CA, 但是在分布式系统大行其道的今天, 满足CA特性的系统很难生存下去。 ACID也逐渐的向BASE转换。

    BASE原理

    BASE(Basically Available、Soft State、Eventual Consistency)
    Basically Available, 基本可用是指分布式系统在出现故障的时候, 允许损失部分可用性, 即保证核心可用。 比如: 电商大促时,为了应对访问量激增, 部分用户可能会被引导到降级页面, 比如为了保证下单可用, 评论无法使用.
    软状态( Soft State)软状态是指允许系统存在中间状态, 而该中间状态不会影响系统整体可用性。 分布式存储中一般一份数据至少会有两到三个副本, 允许不同节点间副本同步的延时就是软状态的体现。
    最终一致性( Eventual Consistency)最终一致性是指系统中的所有数据副本经过一定时间后, 最终能够达到一致的状态。 弱一致性和强一致性相反, 最终一致性是弱一致性的一种特殊情况。
    BASE模型是传统ACID模型的反面,BAlSE强调牺牲高一致性, 从而获得可用性, 数据允许在一段时间内的不一致, 只要保证最终一致就可以了。

    方案

    XA协议的两阶段提交

    原理: XA是由X/Open组织提出的分布式事务的规范,由一个事务管理器(TM)和多个资源管理器(RM)组成, 提交分为两个阶段:prepare和commit
    理解: TM: java里的数据库驱动; RM: 数据库;

    优缺点: 保证数据的强一致性; 效率低下,性能与本地事务相差10倍; commit阶段出现问题,事务出现不一致,需人工处理;
    实现:
    MySql5.7及以上均支持XA协议
    MySql Connector/J5.0以上支持XA协议
    Java系统中,数据源采用Atomikos

    事务补偿机制

    TCC(Try-Confirm-Cancel)
    原理: 针对每个操作都定义一个补偿(撤销)操作, 如果执行失败就调用补偿操作;
    补偿操作也有可能失败, 多次重试; 超过重试次数就记录日志, 人工处理;

    优点: 逻辑清晰、流程简单
    缺点: 数据一致性比XA还要差, 可能出错的点比较多; TCC属于应用层的补偿方式, 需要程序员编写大量代码. 一般不推荐使用这种方式。
    演示: 视频里纯手工控制, 没有现成方案

    基于本地消息表最终一致方案

    BASE原理, 最终一致的实现, 允许一段时间不一致; 根据具体情况决定是否采用;
    本事务之外的操作记录在消息表中, 其他事务提供操作接口; 定时轮询本地消息表, 将未执行的消息发送给操作接口; 记录操作接口执行的结果, 成功还是失败; 失败的操作设置最大失败次数, 最终失败的人工处理;
    流程图:

    优点: 避免了分布式事务, 实现最终一致性
    缺点: 注意重试时的幂等性

    基于MQ事务的最终一致方案

    原理和流程与本地消息表类似;
    不同点: 消息表改为MQ, 定时任务改为MQ的消费者;

    流程图:

    优点: MQ比定时任务更高效、可靠
    缺点: MQ方案适合公司内系统(一个集群内), 不同公司无法基于MQ, 本地消息表更合适;

  • 相关阅读:
    kettle连接MySQL报错
    git切换到某个tag, 从tag切换回当前分支
    wireshark 实用过滤表达式(针对ip、协议、端口、长度和内容)
    linux下python3.6.7安装
    haproxy backup模式
    Oracle_2 随便写写
    Oracle 日期函数练习 随便写写
    RabbitMQ
    X.509标准、CA认证
    docker-compose和Dockerfile的volumes
  • 原文地址:https://www.cnblogs.com/QIAOXINGXING001/p/15472592.html
Copyright © 2011-2022 走看看