Springcloud基础知识(16)- Spring Cloud Alibaba Seata (二) | 事务分组

 

1. 简介

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

    集群:Seata-Server 服务端一个或多个节点组成的集群 cluster。 应用程序(客户端)使用时需要指定事务逻辑分组与 Seata 服务端集群的映射关系。

    事务分组后找到后端 Seata 集群的可能方式:

        (1) 应用程序(客户端)中配置了事务分组(GlobalTransactionScanner 构造方法的 txServiceGroup 参数)。若应用程序是 SpringBoot 则通过 seata.tx-service-group 配置
        (2) 应用程序(客户端)会通过用户配置的配置中心去寻找 “service.vgroupMapping.[事务分组配置项]”,取得配置项的值就是TC集群的名称。若应用程序是 SpringBoot 则通过 “seata.service.vgroup-mapping.事务分组名=集群名称” 配置
        (3) 根据集群名称,程序通过一定的前后缀+集群名称去构造服务名,各配置中心的服务名实现不同(前提是Seata-Server 已经完成服务注册,且 Seata-Server 向注册中心报告 cluster 名与应用程序(客户端)配置的集群名称一致)
        (4) 根据服务名,去相应的注册中心去拉取相应服务名的服务列表,获得后端真实的 TC 服务列表(即 Seata-Server 集群节点列表)

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

    本文使用 “Springcloud基础知识(15)- Spring Cloud Alibaba Seata (一) | Seata 简介、事务模式、Seata Server” 里的 Seata Server 1.4.2,演示默认配置 (file) 下如何使用事务分组。


2. Seata Server 的配置


    1) Seata Server 端的配置 (conf/registry.conf)

 1         registry {
 2             # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
 3             type = "file"
 4         
 5             ...
 6 
 7             file {
 8                 name = "file.conf"
 9             }
10 
11         }
12 
13         config {
14             # file、nacos 、apollo、zk、consul、etcd3
15             type = "file"
16         
17             ...
18 
19             file {
20                 name = "file.conf"
21             }
22         }


    2) 启动 Seata Server

        使用带参数的命令行方式启动,格式如下:

            C:\seata-server-1.4.2\bin>seata-server -p 8092

1             ...
2 
3             22:36:41.922  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is registry
4             22:36:41.926  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is C:\Applications\Java\alibaba-cloud\seata-server-1.4.2\conf\registry.conf
5             22:36:41.985  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is file.conf
6             22:36:41.985  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is C:\Applications\Java\alibaba-cloud\seata-server-1.4.2\conf\file.conf
7             22:36:42.608  INFO --- [                     main] i.s.core.rpc.netty.NettyServerBootstrap  : Server started, listen port: 8092


3. 创建 Seata 客户端


    本文参考 “ Springcould基础知识(1)- 微服务、Spring Cloud 简介、IDEA 创建多模块项目 ” ,创建 SpringcloudDemo05 项目。

    1) 创建 Maven 主项目

        运行 IDEA,点击菜单 New 创建 Project:
        
            New Project -> Project Type: Maven -> Project SDK: 1.8 -> Uncheck "Create from archtype" -> Next

                Name: SpringcloudDemo05
                GroupId: com.example
                ArtifactId: SpringcloudDemo05

            -> Finish

        修改 pom.xml 内容如下:

 1             <?xml version="1.0" encoding="UTF-8"?>
 2             <project xmlns="http://maven.apache.org/POM/4.0.0"
 3                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4                     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
 5                                         http://maven.apache.org/xsd/maven-4.0.0.xsd">
 6                 <parent>
 7                     <groupId>org.springframework.boot</groupId>
 8                     <artifactId>spring-boot-starter-parent</artifactId>
 9                     <version>2.4.2</version>
10                     <relativePath/> <!-- lookup parent from repository -->
11                 </parent>
12 
13                 <modelVersion>4.0.0</modelVersion>
14                 <packaging>pom</packaging>
15 
16                 <groupId>com.example</groupId>
17                 <artifactId>SpringcloudDemo05</artifactId>
18                 <version>1.0-SNAPSHOT</version>
19 
20                 <properties>
21                     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
22                     <maven.compiler.source>1.8</maven.compiler.source>
23                     <maven.compiler.target>1.8</maven.compiler.target>
24                     <junit.version>4.12</junit.version>
25                     <log4j.version>1.2.17</log4j.version>
26                     <lombok.version>1.16.18</lombok.version>
27                     <mariadb.version>2.7.4</mariadb.version>
28                     <mybatis.version>2.2.0</mybatis.version>                
29                     <spring-cloud.version>2020.0.4</spring-cloud.version>
30                     <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
31                 </properties>
32 
33                 <dependencyManagement>
34                     <dependencies>
35                         <!-- Spring Cloud Alibaba 的版本信息 -->
36                         <dependency>
37                             <groupId>com.alibaba.cloud</groupId>
38                             <artifactId>spring-cloud-alibaba-dependencies</artifactId>
39                             <version>${spring-cloud-alibaba.version}</version>
40                             <type>pom</type>
41                             <scope>import</scope>
42                         </dependency>
43                         <!-- Spring Cloud 的版本信息 -->
44                         <dependency>
45                             <groupId>org.springframework.cloud</groupId>
46                             <artifactId>spring-cloud-dependencies</artifactId>
47                             <version>${spring-cloud.version}</version>
48                             <type>pom</type>
49                             <scope>import</scope>
50                         </dependency>
51                     </dependencies>
52                 </dependencyManagement>
53 
54                 <build>
55                     <plugins>
56                         <plugin>
57                             <groupId>org.springframework.boot</groupId>
58                             <artifactId>spring-boot-maven-plugin</artifactId>
59                             <configuration>
60                                 <mainClass>com.example.App</mainClass>
61                                 <layout>JAR</layout>
62                             </configuration>
63                             <executions>
64                                 <execution>
65                                     <goals>
66                                         <goal>repackage</goal>
67                                     </goals>
68                                 </execution>
69                             </executions>
70                         </plugin>
71                     </plugins>
72                 </build>
73 
74             </project>

 

        通过 dependencyManagement 对 Spring Cloud Alibaba 的版本信息进行管理,各子模块在引入 Spring Cloud Alibaba 的组件时不用指定版本号。

    2) 创建 SeataClient 子模块

        选择左上的项目列表中的 SpringcloudDemo05,点击鼠标右键,选择 New -> Module 进入 New Module 页面:

            Maven -> Project SDK: 1.8 -> Check "Create from archtype" -> select "org.apache.maven.archtypes:maven-archtype-quickstart" -> Next

                Name: SeataClient
                GroupId: com.example
                ArtifactId: SeataClient

            -> Finish

    3) 修改 pom.xml,内容如下。

 1         <?xml version="1.0" encoding="UTF-8"?>
 2         <project xmlns="http://maven.apache.org/POM/4.0.0"
 3                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
 5                                     http://maven.apache.org/xsd/maven-4.0.0.xsd">
 6             <parent>
 7                 <artifactId>SpringcloudDemo05</artifactId>
 8                 <groupId>com.example</groupId>
 9                 <version>1.0-SNAPSHOT</version>
10             </parent>
11             <modelVersion>4.0.0</modelVersion>
12 
13             <artifactId>SeataClient</artifactId>
14 
15             <name>SeataClient</name>
16             <!-- FIXME change it to the project's website -->
17             <url>http://www.example.com</url>
18 
19             <properties>
20                 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
21                 <maven.compiler.source>1.8</maven.compiler.source>
22                 <maven.compiler.target>1.8</maven.compiler.target>
23                 <maven.install.skip>true</maven.install.skip>
24             </properties>
25 
26             <dependencies>
27                 <dependency>
28                     <groupId>junit</groupId>
29                     <artifactId>junit</artifactId>
30                     <scope>test</scope>
31                 </dependency>
32 
33                 <dependency>
34                     <groupId>org.springframework.boot</groupId>
35                     <artifactId>spring-boot-starter-web</artifactId>
36                 </dependency>        
37                 <dependency>
38                     <groupId>org.springframework.boot</groupId>
39                     <artifactId>spring-boot-starter-test</artifactId>
40                     <scope>test</scope>
41                 </dependency>
42 
43                 <!-- seata -->
44                 <dependency>
45                     <groupId>com.alibaba.cloud</groupId>
46                     <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
47                 </dependency>
48 
49             </dependencies>
50 
51         </project>
52 


    4) 创建 src/main/resources/application.yml 文件

 1         server:
 2             port: 4001  # 端口号
 3 
 4         spring:
 5             application:
 6                 name: seata-client-4001  # 服务名
 7 
 8         seata:
 9             #enabled: true
10             application-id: ${spring.application.name}
11             tx-service-group: default_tx_group      # 默认值,有的版本使用 my_test_tx_group
12             service:
13                 vgroupMapping:      # 这里使用 vgroupMapping 和 vgroup-mapping 都可以
14                     default_tx_group: default
15                 grouplist:
16                     default: 127.0.0.1:8092


        配置说明:

            a) 获取事务分组(服务启动时加载配置): SeataClient 读取 application.yml 里 seata.tx-service-group 的值 “default_tx_group” (默认值,有的版本使用 "my_test_tx_group");

                注:若 application.yml 里没有配置 seata.tx-service-group 项,自动以 spring.application.name的值 + "-seata-service-group" 拼接后的字符串作为分组名。
                
                    此时 seata 的配置应该如下。

1                         seata:
2                             #enabled: true
3                             application-id: ${spring.application.name}
4                             #tx-service-group: default_tx_group      # 默认值,有的版本使用 my_test_tx_group
5                             service:
6                                 vgroupMapping:      # 这里使用 vgroupMapping 和 vgroup-mapping 都可以
7                                     seata-client-4001-seata-service-group: default
8                                 grouplist:
9                                     default: 127.0.0.1:8092


            b) 查找 TC 集群名 (clusterName): SeataClient 读取 seata.service.vgroupMapping.default_tx_group 的值 "default",即 TC 集群名 (clusterName)。

                注:这里使用 “vgroupMapping” 和 “vgroup-mapping” 都可以。

            c) 查询 TC 服务: SeataClient 读取 seata.service.grouplist.default 的值 “127.0.0.1:8092”,即 TC 服务真实地址。
   
    5) 修改 src/main/java/com/example/App.java 文件

 1         package com.example;
 2 
 3         import org.springframework.boot.SpringApplication;
 4         import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 
 6         @SpringBootApplication
 7         public class App {
 8             public static void main(String[] args) {
 9                 SpringApplication.run(App.class, args);
10             }
11         }


    6) 运行 SeataClient

        菜单 Run -> Edit Configurations (或工具条上选择) —> 进入 Run/Debug Configurations 页面 -> Click "+" add new configuration -> Select "Maven":

            Working directory: SeataClient 所在路径
            Command line: clean spring-boot:run

        -> Apply / OK

        点击 Run "SeataClient [clean, spring-boot:run]" ,控制台输出如下:

 1             ...
 2 
 3             INFO 52548 --- [           main] com.example.App                          : Started App in 1.366 seconds (JVM running for 1.677)
 4             INFO 52548 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager  : will connect to 127.0.0.1:8092
 5             INFO 52548 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory  : NettyPool create channel to transactionRole:TMROLE,address:127.0.0.1:8092,msg:< RegisterTMRequest{applicationId='seata-client-4001', transactionServiceGroup='default_tx_group'} >
 6             INFO 52548 --- [eoutChecker_2_1] i.s.c.r.netty.NettyClientChannelManager  : will connect to 127.0.0.1:8092
 7             INFO 52548 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory  : NettyPool create channel to transactionRole:RMROLE,address:127.0.0.1:8092,msg:< RegisterRMRequest{resourceIds='null', applicationId='seata-client-4001', transactionServiceGroup='default_tx_group'} >
 8             INFO 52548 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient    : register RM success. client version:1.3.0, server version:1.4.2,channel:[id: 0xfb78406b, L:/127.0.0.1:49690 - R:/127.0.0.1:8092]
 9             INFO 52548 --- [eoutChecker_1_1] i.s.c.rpc.netty.TmNettyRemotingClient    : register TM success. client version:1.3.0, server version:1.4.2,channel:[id: 0xd35a9b4c, L:/127.0.0.1:49691 - R:/127.0.0.1:8092]
10             INFO 52548 --- [eoutChecker_1_1] i.s.core.rpc.netty.NettyPoolableFactory  : register success, cost 36 ms, version:1.4.2,role:TMROLE,channel:[id: 0xd35a9b4c, L:/127.0.0.1:49691 - R:/127.0.0.1:8092]
11             INFO 52548 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory  : register success, cost 36 ms, version:1.4.2,role:RMROLE,channel:[id: 0xfb78406b, L:/127.0.0.1:49690 - R:/127.0.0.1:8092]


        注:使用 spring-cloud-starter-alibaba-seata 或 seata-spring-boot-starter 的 seata 客户端默认是开启状态 (可以设置 seata.enabled=false 来关闭)。


    seata 客户端里包含了一个全局事务扫描器 (GlobalTransactionScanner),seata 客户端运行后(30 秒左右)GlobalTransactionScanner 会调用初始化功能,使用 netty 连接 Seata 服务端。

    从 log 可以看出 SeataClient 成功连接到了 Seata Server (127.0.0.1:8092)。



  

posted @ 2022-07-29 21:09  垄山小站  阅读(847)  评论(0)    收藏  举报