Seata入门系列【5】事务分组原理及应用案例详解

news2024/11/17 13:58:38

1 事务分组

1.1 概念

事务分组:seata的资源逻辑,可以按微服务的需要,在应用程序(客户端)对自行定义事务分组,每组取一个名字。

例如以下配置中,定义了当前事务分组名为${spring.application.name}-tx-group

seata:
  # 是否开启spring-boot自动装配,默认true,包括数据源的自动代理以及GlobalTransactionScanner初始化
  enabled: true
  # 应用ID
  application-id: ${spring.application.name}
  # 事务分组名
  tx-service-group: ${spring.application.name}-tx-group
  # 事务分组映射
  service:
    vgroupMapping:
      demo002-tx-group: "default"

在部署Seata 服务端时,是可以设置集群名称的,默认为default,在Nacos中可以看到集群名

在这里插入图片描述
可以通过registry.conf配置文件,修改当前的集群名:
在这里插入图片描述
查看Nacos,可以看到当前存在两个Seata 集群,名称分别为default、c1
在这里插入图片描述集群模式下seata-server服务端由一个或多个节点组成。 应用程序(客户端)使用时需要指定事务逻辑分组与Seata服务端集群的映射关系。

比如之前我们定义当前后台的事务分组为demo002-tx-group,然后需要使用seata.service.vgroupMapping.事务分组名:集群名称来配置分组和集群的映射关系。这表示当前应用绑定的是名为default的集群。

 # 事务分组映射
  service:
    vgroupMapping:
      demo002-tx-group: "default"

1.2 事务分组如何找到后端Seata集群?

1.2.1 配置事务分组名

应用程序(客户端)中配置了事务分组(GlobalTransactionScanner 构造方法的txServiceGroup参数)。

比如以下,demo002项目配置的事务分组名为:demo002-tx-group

seata:
  # 是否开启spring-boot自动装配,默认true,包括数据源的自动代理以及GlobalTransactionScanner初始化
  enabled: true
  # 应用ID
  application-id: ${spring.application.name}
  # 分组名
  tx-service-group: ${spring.application.name}-tx-group

当没有配置时,默认规则如下:

txServiceGroup = ${spring.application.name}+ "-seata-service-group";

1.2.2 配置事务分组名和集群名的映射关系

应用程序(客户端)还需要配置当前事务分组和TC集群的绑定关系。

若应用程序是SpringBoot则通过seata.service.vgroupMapping.事务分组名=集群名称 配置:

seata:
  # 事务分组映射
  service:
    vgroupMapping:
      demo002-tx-group: "default"

如果没有配置,默认为seata.service.vgroupMapping.my_test_tx_group=default,默认的事务分组名为xx–seata-service-group,如果不配置,就会报错。。。这里官方是否应该优化下,设置my_test_tx_group为默认的事务分组名。

if (0 == this.vgroupMapping.size()) {
            this.vgroupMapping.put("my_test_tx_group", "default");
        }

单个项目下的多个后台服务,配置一个分组就可以了,不需要每个服务都单独配置。

1.2.3 获得TC服务列表

配置好当前应用程序(客户端)的服务分组名和集群名后,启动Seata 注册到注册中心中,启动后台程序时,客户端会根据事务分组名绑定的TC 集群名,去注册中心中获取真实的TC服务列表(即Seata-Server集群节点列表)。

其核心代码在NacosRegistryServiceImpl类中

public List<InetSocketAddress> lookup(String key) throws Exception {
    	// 1. 通过分组获取配置TC集群名。demo001-tx-group=》default
        String clusterName = this.getServiceGroup(key);
        if (clusterName == null) {
            return null;
        } else {
            if (!LISTENER_SERVICE_MAP.containsKey(clusterName)) {
                synchronized(LOCK_OBJ) {
                    if (!LISTENER_SERVICE_MAP.containsKey(clusterName)) {
                        List<String> clusters = new ArrayList();
                        clusters.add(clusterName);
                        // 2. 注册中心获取Seata 实例
                        // 参数getServiceName():registry.type.nacos.application配置的值=》seata-server
                        // 参数getServiceGroup():registry.type.nacos.group配置的值=》SEATA_GROUP
                        // 参数clusters:配置的TC集群名=》default
                        List<Instance> firstAllInstances = getNamingInstance().getAllInstances(getServiceName(), getServiceGroup(), clusters);
                        // 省略其他代码....
                        });
                    }
                }
            }
			// 返回真实TC 列表
            return (List)CLUSTER_ADDRESS_MAP.get(clusterName);
        }
    }

客户端通过注册中心获取到的Seata实例信息如下:

Instance{instanceId='192.168.1.240#8092#default#SEATA_GROUP@@seata-server',
 ip='192.168.1.240', 
 port=8092, 
 weight=1.0,
 healthy=true, 
 enabled=true, 
 ephemeral=true, 
 clusterName='default', 
 serviceName='SEATA_GROUP@@seata-server', 
 metadata={}}

最终通过服务分组名配置的集群名称,在Nacos中获取到了真实的TC服务列表。

在这里插入图片描述

1.3 为什么这么设计,不直接取服务名?

这里多了一层获取事务分组到映射集群的配置。这样设计后,事务分组可以作为资源的逻辑隔离单位,出现某集群故障时可以快速failover,只切换对应分组,可以把故障缩减到服务级别,但前提也是你有足够server集群。

2 应用案例

事务分组的主要作用是,集群环境下,存在多个集群时,如果某个集群宕机,我们直接直接切换到可用集群。
官网地址:https://yunyanchengyu.blog.csdn.net/article/details/122700308

2.1 最佳实践1:TC的异地多机房容灾

  • 假定TC集群部署在两个机房:guangzhou机房(主)和shanghai机房(备)各两个实例

  • 一整套微服务架构项目:projectA

  • projectA内有微服务:serviceA、serviceB、serviceC 和 serviceD

其中,projectA所有微服务的事务分组tx-service-group设置为:projectA,projectA正常情况下使用guangzhou的TC集群(主)

那么正常情况下,client端的配置如下所示:

seata.tx-service-group=projectA
seata.service.vgroup-mapping.projectA=Guangzhou

在这里插入图片描述
假如此时guangzhou集群分组整个down掉,或者因为网络原因projectA暂时无法与Guangzhou机房通讯,那么我们将配置中心中的Guangzhou集群分组改为Shanghai,如下:

seata.service.vgroup-mapping.projectA=Shanghai

并推送到各个微服务,便完成了对整个projectA项目的TC集群动态切换。
在这里插入图片描述

2.2 最佳实践2:单一环境多应用接入

  • 假设现在开发环境(或预发/生产)中存在一整套seata集群

  • seata集群要服务于不同的微服务架构项目projectA、projectB、projectC

  • projectA、projectB、projectC之间相对独立

我们将seata集群中的六个实例两两分组,使其分别服务于projectA、projectB与projectC,那么此时seata-server端的配置如下(以nacos注册中心为例):

registry {
  type = "nacos"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  nacos {
    application = "seata-server"
    serverAddr = "127.0.0.1:8848"
    group = "DEFAULT_GROUP"
    namespace = "8f11aeb1-5042-461b-b88b-d47a7f7e01c0"
    #同理在其他几个分组seata-server实例配置 project-b-group / project-c-group
    cluster = "project-a-group"
    username = "username"
    password = "password"
  }
}

client端的配置如下:

seata.tx-service-group=projectA
#同理,projectB与projectC配置 project-b-group / project-c-group
seata.service.vgroup-mapping.projectA=project-a-group

完成配置启动后,对应事务分组的TC单独为其应用服务,整体部署图如下:
在这里插入图片描述

2.3 最佳实践3:client的精细化控制

  • 假定现在存在seata集群,Guangzhou机房实例运行在性能较高的机器上,Shanghai集群运行在性能较差的机器上

  • 现存微服务架构项目projectA、projectA中有微服务ServiceA、ServiceB、ServiceC与ServiceD

  • 其中ServiceD的流量较小,其余微服务流量较大

那么此时,我们可以将ServiceD微服务引流到Shanghai集群中去,将高性能的服务器让给其余流量较大的微服务(反之亦然,若存在某一个微服务流量特别大,我们也可以单独为此微服务开辟一个更高性能的集群,并将该client的virtual group指向该集群,其最终目的都是保证在流量洪峰时服务的可用)
在这里插入图片描述

2.4 最佳实践4:Seata的预发与生产隔离

  • 大多数情况下,预发环境与生产环境会使用同一套数据库。基于这个条件,预发TC集群与生产TC集群必须使用同一个数据库保证全局事务的生效(即生产TC集群与预发TC集群使用同一个lock表,并使用不同的branch_table与global_table的情况)

  • 我们记生产使用的branch表与global表分别为:global_table与branch_table;预发为global_table_pre,branch_table_pre

  • 预发与生产共用lock_table

此时,seata-server的 file.conf 配置如下

store {
  mode = "db"

  db {
    datasource = "druid"
    dbType = "mysql"
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://127.0.0.1:3306/seata"
    user = "username"
    password = "password"
    minConn = 5
    maxConn = 100
    globalTable = "global_table"  ----> 预发为 "global_table_pre"
    branchTable = "branch_table"  ----> 预发为 "branch_table_pre"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }
}

seata-server的 registry.conf 配置如下(以nacos为例)

registry {
  type = "nacos"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  nacos {
    application = "seata-server"
    serverAddr = "127.0.0.1:8848"
    group = "DEFAULT_GROUP"
    namespace = "8f11aeb1-5042-461b-b88b-d47a7f7e01c0"
    cluster = "pre-product"  -->同理生产为 "product"
    username = "username"
    password = "password"
  }
}

其部署图如下所示:
在这里插入图片描述
不仅如此,你还可以将以上四个最佳实践依据你的实际生产情况组合搭配使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1084009.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

凉鞋的 Unity 笔记 108. 第二个通识:增删改查

在这一篇&#xff0c;我们来学习此教程的第二个通识&#xff0c;即&#xff1a;增删改查。 增删改查我们不只是一次接触到了。 在最先接触的场景层次窗口中&#xff0c;我们是对 GameObject 进行增删改查。 在 Project 文件窗口中&#xff0c;我们是对文件&文件夹进行增删…

Elasticsearch —索引性能技巧

目录 一、科学的测试性能 二、使用批量请求并调整其大小 三、存储 四、段和合并 五、其他 如果你是在一个索引负载很重的环境&#xff0c;比如索引的是基础设施日志&#xff0c;你可能愿意牺牲一些搜索性能换取更快的索引速率。在这些场景里&#xff0c;搜索常常是很少见的…

数据结构题型17-树、森林

文章目录 1 树转换为二叉树2 森林转换为二叉树3 二叉树转换为树4 二叉树转换为森林 1 树转换为二叉树 参考博客&#xff1a;如何将一棵树转化成二叉树 2 森林转换为二叉树 参考博客&#xff1a;树、森林与二叉树的转换 3 二叉树转换为树 参考博客&#xff1a;树、森林与…

开山之作 | YOLOv1算法超详细解析(包括诞生背景+论文解析+技术原理等)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。目标检测是计算机视觉领域的一项重要研究方向&#xff0c;它在许多应用领域中都得到了广泛应用&#xff0c;如人脸识别、物体识别、自动驾驶、视频监控等。在过去&#xff0c;目标检测方法主要采用基于RCNN、Fast R-CNN等深…

软件工程与计算总结(九)软件体系结构基础

目录 ​编辑 一.体系结构的发展 二.理解体系结构 1.定义 2.区分体系结构的抽象与实现 3.部件 4.连接件 5.配置 三.体系结构风格初步 1.主程序/子程序 2.面向对象式 3.分层 4.MVC 一.体系结构的发展 小规模编程的重点在于模块内部的程序结构非常依赖于程序设计语言…

学网络安全的过程 ,差点要了我的命

我真的好像感慨一下&#xff0c;这个世界真的给计算机应届生留活路了吗&#xff1f; 看着周围的同学&#xff0c;打算搞前端、JAVA、C、C的&#xff0c;一个两个去跑去应聘。你以为是00后整治职场&#xff1f; 真相是主打一个卑微&#xff1a;现阶段以学习为主&#xff08;工资…

在Linux中掌握不同的命令,让创建文件变得易如反掌

在Linux中创建一个新文件很简单,但也有一些令人惊讶和灵巧的技术。​在本教程中,学习如何从Linux终端创建文件。​ 先决条件 访问命令行/终端窗口(Ctrl-Alt-F2或Ctrl-Alt-T) 具有sudo权限的用户帐户(对于某些文件/目录是可选的) 从命令行创建新的Linux文件 Linux的设计…

TXT文件恢复,简单3招,快速恢复文件!

“由于工作需要&#xff0c;我的电脑中保存了很多的TXT文件&#xff0c;但是在清内存时&#xff0c;我不小心删除了一些比较重要的文件&#xff0c;请问有什么方法可以恢复吗&#xff1f;” TXT文件是一种普通的文本文件格式&#xff0c;它包含了纯文本信息&#xff0c;没有任何…

股票价格预测 | Python基于RNN及股票预测实战

循环神经网络(RNN)是基于序列数据(如语言、语音、时间序列)的递归性质而设计的,是一种反馈类型的神经网络,其结构包含环和自重复,因此被称为“循环”。它专门用于处理序列数据,如逐字生成文本或预测时间序列数据(例如股票价格)。 (1)one to one:其实和全连接神经网络…

Pycharm 2023 设置远程调试

pycharm 版本 &#xff1a; 2023.2.1 整体流程参考&#xff1a;https://blog.csdn.net/xuanhaolaile/article/details/128293254 首先确定远程服务器上已经安装好 requirements.txt 中所需的依赖包。 1、SSH Configurations 添加远程服务器 2、Python Interpreter 注意&…

别再使用循环的方式筛选元素了!开发常用的Stream流+Lambda表达式过滤元素了解过吗?10000字超详细解析

目录 1. Stream 流的简单展示 1.1 抛出问题 1.2 传统解决问题的编码方式 1.3 Stream 流的方式过滤元素 2. Stream 流的核心思想 3. Stream 流的使用 3.1 获取 stream 流 3.1.1 单列集合获取 stream 流 3.1.2 双列集合获取 stream 流 3.1.3 数组获取 stream 流 3.1.4…

AD20统一修改相同元器件的名称和标号的方法

如图所示&#xff0c;我们原理图中有很多开关&#xff0c;比如说名字乱七八遭&#xff0c;想要整体快速修改应该怎么办呢&#xff1f; 解决方法&#xff1a;把鼠标指针放到原理图的空白处单击鼠标右键 点击查找相似对象之后鼠标变成了一个十字状&#xff0c;用十字状中心点击要…

凉鞋的 Godot 笔记 108. 第二个通识:增删改查

在这一篇&#xff0c;我们来学习此教程的第二个通识&#xff0c;即&#xff1a;增删改查。 增删改查我们不只是一次接触到了。 在最先接触的场景窗口中&#xff0c;我们是对 Node 进行增删改查。 在文件系统窗口中&#xff0c;我们是对文件&文件夹进行增删改查&#xff1…

Linux工具-远程登录/访问

测试环境&#xff1a;ubuntu 20.04 一、ssh服务 SSH&#xff08;Secure Shell Protocol&#xff0c;安全的壳程序协议&#xff0c;基于tcp协议默认使用22端口&#xff09;&#xff0c;它可以通过数据包加密技术将待传输的数据包加密后再传输到网络上。通过ssh协议/服务&#…

ros之乌龟做圆周运动and订阅乌龟的位姿信息

一 .基于乌龟显示节点&#xff0c;通过话题发布&#xff0c;编码实现控制小乌龟做圆周运动 打开终端1&#xff0c;进入工作空间 ros_ws cd ros_ws启动节点(ros服务器) roscore新开终端2&#xff0c;启动乌龟节点&#xff08;turtlesim &#xff09; rosrun turtlesim turtl…

企业数字化营销策略如何制定?企业开展数字化营销有的关键步骤?

​制定数字化营销策略是建立数字化营销体系的关键步骤&#xff0c;想要建立好的数字化营销策划&#xff0c;需要企业明确目标客户群体&#xff0c;通过了解他们的需求和行为&#xff0c;来制定相应的营销策略。例如&#xff0c;通过数据分析手段&#xff0c;企业可以确定目标客…

#JavaScript教程:循环遍历@FDDLC

一、普通的for循环&#xff08;当然还有while循环和do while循环&#xff09; 二、for of 遍历 三、for in 遍历 四、forEach 五、map方法 六、reduce方法 输出&#xff1a;543 七、filter方法 八、some方法

TensorFlow入门(二十三、退化学习率)

学习率 学习率,控制着模型的学习进度。模型训练过程中,如果学习率的值设置得比较大,训练速度会提升,但训练结果的精度不够,损失值容易爆炸;如果学习率的值设置得比较小,精度得到了提升,但训练过程会耗费太多的时间,收敛速度慢,同时也容易出现过拟合的情况。 退化学习率 退化学…

mysql误删误操作恢复数据,比传统方式和binlog2sql更快速用的恢复方式-reverse_sql恢复数据(单表多表)

场景&#xff1a; 误操作删除了某个表的数据&#xff0c;本文只讲工具的使用&#xff0c;首先自己通过mysqlbinlog或者记录找到误操作的时间范围&#xff1a;开始时间和结束时间&#xff0c;已经确定好是哪个binlog了下面以误删为例。 查看binlog是否开启 show variables like …

2023影视源接口分享 影视仓配置接口大全 TVBox接口地址源 订阅源地址大全

如今有着大量以TVBox为原版开发出的影视TV软件&#xff0c;这软件软件盒子本身不能观看影视&#xff0c;但是能够通过添加影视源的方式畅看影视&#xff0c;并且这些影视源能够在这款类型的软件中共用&#xff0c;非常的方便&#xff0c;今天小编将为用户提供丰富的影视源和直播…