Quellcode durchsuchen

add 整合 seata 1.4.2 对接 nacos 注册中心 配置中心

疯狂的狮子li vor 4 Jahren
Ursprung
Commit
0c2efd36cf

+ 6 - 9
config/dev/application.yml

@@ -210,20 +210,17 @@ seata:
   application-id: ${spring.application.name}
   # Seata 事务组编号,用于 TC 集群名
   tx-service-group: ${spring.application.name}-group
-  # 服务配置项
-  service:
-    # 虚拟组和分组的映射
-    vgroup-mapping:
-      ${spring.application.name}: default
   config:
     type: nacos
     nacos:
-      serverAddr: ${spring.cloud.nacos.server-addr}
-      group: SEATA_GROUP
-      namespace:
+      server-addr: ${spring.cloud.nacos.server-addr}
+      group: ${spring.cloud.nacos.config.group}
+      namespace: ${spring.profiles.active}
+      data-id: seata-server.properties
   registry:
     type: nacos
     nacos:
       application: seata-server
       server-addr: ${spring.cloud.nacos.server-addr}
-      namespace:
+      group: ${spring.cloud.nacos.discovery.group}
+      namespace: ${spring.profiles.active}

+ 5 - 6
config/dev/ruoyi-system.yml

@@ -17,12 +17,11 @@ spring:
           username: ${datasource.system-master.username}
           password: ${datasource.system-master.password}
         # 从库数据源
-        slave:
-          lazy: true
-          driver-class-name:
-          url:
-          username:
-          password:
+        # slave:
+        #  driver-class-name:
+        #  url:
+        #  username:
+        #  password:
 
 xxl:
   job:

+ 47 - 0
config/dev/seata-server.properties

@@ -0,0 +1,47 @@
+service.vgroupMapping.ruoyi-auth-group=default
+service.vgroupMapping.ruoyi-system-group=default
+service.vgroupMapping.ruoyi-file-group=default
+service.enableDegrade=false
+service.disableGlobalTransaction=false
+store.mode=db
+store.publicKey=
+store.db.datasource=druid
+store.db.dbType=mysql
+store.db.driverClassName=com.mysql.cj.jdbc.Driver
+store.db.url=jdbc:mysql://172.30.0.36:3306/ry-seata?useUnicode=true&rewriteBatchedStatements=true
+store.db.user=root
+store.db.password=root
+store.db.minConn=5
+store.db.maxConn=30
+store.db.globalTable=global_table
+store.db.branchTable=branch_table
+store.db.distributedLockTable=distributed_lock
+store.db.queryLimit=100
+store.db.lockTable=lock_table
+store.db.maxWait=5000
+server.recovery.committingRetryPeriod=1000
+server.recovery.asynCommittingRetryPeriod=1000
+server.recovery.rollbackingRetryPeriod=1000
+server.recovery.timeoutRetryPeriod=1000
+server.maxCommitRetryTimeout=-1
+server.maxRollbackRetryTimeout=-1
+server.rollbackRetryTimeoutUnlockEnable=false
+server.distributedLockExpireTime=10000
+client.undo.dataValidation=true
+client.undo.logSerialization=kryo
+client.undo.onlyCareUpdateColumns=true
+server.undo.logSaveDays=7
+server.undo.logDeletePeriod=86400000
+client.undo.logTable=undo_log
+client.undo.compress.enable=true
+client.undo.compress.type=zip
+client.undo.compress.threshold=64k
+log.exceptionRate=100
+transport.serialization=seata
+transport.compressor=none
+metrics.enabled=false
+metrics.registryType=compact
+metrics.exporterList=prometheus
+metrics.exporterPrometheusPort=9898
+tcc.fence.logTableName=tcc_fence_log
+tcc.fence.cleanPeriod=1h

+ 28 - 0
docker/seata/registry.conf

@@ -0,0 +1,28 @@
+registry {
+  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
+  type = "nacos"
+
+  nacos {
+    application = "seata-server"
+    serverAddr = "172.30.0.40:8848"
+    group = "DEFAULT_GROUP"
+    namespace = "dev"
+    cluster = "default"
+    username = ""
+    password = ""
+  }
+}
+
+config {
+  # file、nacos 、apollo、zk、consul、etcd3
+  type = "nacos"
+
+  nacos {
+    serverAddr = "172.30.0.40:8848"
+    group = "DEFAULT_GROUP"
+    namespace = "dev"
+    username = ""
+    password = ""
+    dataId = "seata-server.properties"
+  }
+}

+ 7 - 0
pom.xml

@@ -40,6 +40,7 @@
         <redisson.version>3.16.7</redisson.version>
         <lock4j.version>2.2.1</lock4j.version>
         <dubbo.version>2.7.15</dubbo.version>
+        <seata.version>1.4.2</seata.version>
         <spring.context.support.version>1.0.11</spring.context.support.version>
         <xxl-job.version>2.3.0</xxl-job.version>
         <knife4j-aggregation.version>2.0.9</knife4j-aggregation.version>
@@ -120,6 +121,12 @@
                 <version>${dubbo.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>io.seata</groupId>
+                <artifactId>seata-spring-boot-starter</artifactId>
+                <version>${seata.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>com.alibaba.spring</groupId>
                 <artifactId>spring-context-support</artifactId>

+ 5 - 0
ruoyi-auth/pom.xml

@@ -56,6 +56,11 @@
             <artifactId>ruoyi-common-dubbo</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common-seata</artifactId>
+        </dependency>
+
         <!-- 自定义负载均衡(多团队开发使用) -->
 <!--        <dependency>-->
 <!--            <groupId>com.ruoyi</groupId>-->

+ 1 - 0
ruoyi-common/pom.xml

@@ -21,6 +21,7 @@
         <module>ruoyi-common-web</module>
         <module>ruoyi-common-job</module>
         <module>ruoyi-common-dubbo</module>
+        <module>ruoyi-common-seata</module>
         <module>ruoyi-common-loadbalancer</module>
     </modules>
 

+ 7 - 0
ruoyi-common/ruoyi-common-bom/pom.xml

@@ -89,6 +89,13 @@
                 <artifactId>ruoyi-common-dubbo</artifactId>
                 <version>${project.version}</version>
             </dependency>
+
+            <dependency>
+                <groupId>com.ruoyi</groupId>
+                <artifactId>ruoyi-common-seata</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>com.ruoyi</groupId>
                 <artifactId>ruoyi-common-loadbalancer</artifactId>

+ 35 - 41
ruoyi-common/ruoyi-common-datasource/pom.xml

@@ -1,41 +1,35 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xmlns="http://maven.apache.org/POM/4.0.0"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>com.ruoyi</groupId>
-        <artifactId>ruoyi-common</artifactId>
-        <version>0.3.0</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-    
-    <artifactId>ruoyi-common-datasource</artifactId>
-	
-    <description>
-        ruoyi-common-datasource多数据源
-    </description>
-
-    <dependencies>
-
-		<!-- Druid -->
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>druid-spring-boot-starter</artifactId>
-            <version>${druid.version}</version>
-        </dependency>
-
-        <!-- Dynamic DataSource -->
-        <dependency>
-            <groupId>com.baomidou</groupId>
-            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
-            <version>${dynamic-ds.version}</version>
-        </dependency>
-        
-        <!-- SpringBoot Seata -->
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
-
-    </dependencies>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>com.ruoyi</groupId>
+        <artifactId>ruoyi-common</artifactId>
+        <version>0.3.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-common-datasource</artifactId>
+
+    <description>
+        ruoyi-common-datasource多数据源
+    </description>
+
+    <dependencies>
+
+		<!-- Druid -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${druid.version}</version>
+        </dependency>
+
+        <!-- Dynamic DataSource -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+            <version>${dynamic-ds.version}</version>
+        </dependency>
+
+    </dependencies>
+</project>

+ 0 - 26
ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/env/ApplicationSeataInitializer.java

@@ -1,26 +0,0 @@
-package com.ruoyi.common.datasource.env;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.env.EnvironmentPostProcessor;
-import org.springframework.core.Ordered;
-import org.springframework.core.env.ConfigurableEnvironment;
-
-/**
- * seata 在 springboot 2.6.x 存在循环引用问题的处理
- *
- * @author ruoyi
- */
-public class ApplicationSeataInitializer implements EnvironmentPostProcessor, Ordered
-{
-    @Override
-    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application)
-    {
-        System.setProperty("spring.main.allow-circular-references", "true");
-    }
-
-    @Override
-    public int getOrder()
-    {
-        return Ordered.LOWEST_PRECEDENCE;
-    }
-}

+ 1 - 2
ruoyi-common/ruoyi-common-datasource/src/main/resources/META-INF/spring.factories

@@ -1,2 +1 @@
-org.springframework.boot.env.EnvironmentPostProcessor=\
-    com.ruoyi.common.datasource.env.ApplicationSeataInitializer
+org.springframework.boot.env.EnvironmentPostProcessor=

+ 39 - 0
ruoyi-common/ruoyi-common-seata/pom.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>com.ruoyi</groupId>
+        <artifactId>ruoyi-common</artifactId>
+        <version>0.3.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-common-seata</artifactId>
+
+    <description>
+        ruoyi-common-seata 分布式事务
+    </description>
+
+	<dependencies>
+
+        <!-- SpringBoot Seata -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
+        </dependency>
+
+        <!-- 用于修复 seata 序列化问题 -->
+        <dependency>
+            <groupId>com.esotericsoftware</groupId>
+            <artifactId>kryo</artifactId>
+            <version>4.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>de.javakaffee</groupId>
+            <artifactId>kryo-serializers</artifactId>
+            <version>0.45</version>
+        </dependency>
+
+    </dependencies>
+</project>

+ 1 - 0
ruoyi-common/ruoyi-common-seata/src/main/resources/META-INF/spring.factories

@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=

+ 5 - 0
ruoyi-modules/ruoyi-file/pom.xml

@@ -70,6 +70,11 @@
             <artifactId>ruoyi-common-dubbo</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common-seata</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-common-web</artifactId>

+ 5 - 6
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java

@@ -5,9 +5,8 @@ import com.ruoyi.common.core.utils.file.FileUtils;
 import com.ruoyi.file.api.domain.SysFile;
 import com.ruoyi.file.service.ISysFileService;
 import io.swagger.annotations.Api;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
@@ -18,12 +17,12 @@ import org.springframework.web.multipart.MultipartFile;
  * @author ruoyi
  */
 @Api(tags = "文件处理")
+@Slf4j
+@RequiredArgsConstructor
 @RestController
 public class SysFileController {
-    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
 
-    @Autowired
-    private ISysFileService sysFileService;
+    private final ISysFileService sysFileService;
 
     /**
      * 文件上传请求

+ 3 - 0
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/dubbo/RemoteFileServiceImpl.java

@@ -31,6 +31,9 @@ public class RemoteFileServiceImpl implements RemoteFileService {
      */
     @Override
     public SysFile upload(String name, String originalFilename, String contentType, byte[] file) {
+        // todo 临时用于测试 seata
+        // throw new ServiceException("上传文件失败");
+
         MultipartFile multipartFile = getMultipartFile(name, originalFilename, contentType, file);
         try {
             // 上传并返回访问地址

+ 19 - 19
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java

@@ -1,19 +1,19 @@
-package com.ruoyi.file.service;
-
-import org.springframework.web.multipart.MultipartFile;
-
-/**
- * 文件上传接口
- *
- * @author ruoyi
- */
-public interface ISysFileService {
-    /**
-     * 文件上传接口
-     *
-     * @param file 上传的文件
-     * @return 访问地址
-     * @throws Exception
-     */
-    public String uploadFile(MultipartFile file) throws Exception;
-}
+package com.ruoyi.file.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 文件上传接口
+ *
+ * @author ruoyi
+ */
+public interface ISysFileService {
+    /**
+     * 文件上传接口
+     *
+     * @param file 上传的文件
+     * @return 访问地址
+     * @throws Exception
+     */
+    String uploadFile(MultipartFile file) throws Exception;
+}

+ 5 - 0
ruoyi-modules/ruoyi-system/pom.xml

@@ -86,6 +86,11 @@
             <artifactId>ruoyi-common-dubbo</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common-seata</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-common-job</artifactId>

+ 4 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java

@@ -108,9 +108,13 @@ public class SysProfileController extends BaseController {
     /**
      * 头像上传
      */
+    // @GlobalTransactional(rollbackFor = Exception.class)
     @Log(title = "用户头像", businessType = BusinessType.UPDATE)
     @PostMapping("/avatar")
     public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException {
+        // todo 临时用于测试 seata
+        // userService.insertUser(new SysUser().setUserName("test").setNickName("test"));
+
         if (!file.isEmpty()) {
             LoginUser loginUser = SecurityUtils.getLoginUser();
             SysFile sysFile = remoteFileService.upload(file.getName(), file.getOriginalFilename(), file.getContentType(), file.getBytes());

+ 4 - 1
sql/ry_config.sql

@@ -43,6 +43,8 @@ insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_mod
 (9, 'ruoyi-file.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:20:35', '2022-01-09 15:21:21', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '文件服务', NULL, NULL, 'yaml', NULL),
 (10, 'sentinel-ruoyi-gateway.json', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '限流策略', NULL, NULL, 'json', NULL),
 (11, 'ruoyi-xxl-job-admin.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', '定时任务控制台', NULL, NULL, 'yaml', NULL),
+(12, 'seata-server.properties', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', 'seata配置文件', NULL, NULL, 'properties', NULL),
+
 (101, 'application.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '通用配置基础配置', NULL, NULL, 'yaml', NULL),
 (102, 'datasource.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '数据源配置', NULL, NULL, 'yaml', NULL),
 (103, 'ruoyi-gateway.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '网关模块', NULL, NULL, 'yaml', NULL),
@@ -53,7 +55,8 @@ insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_mod
 (108, 'ruoyi-job.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务', NULL, NULL, 'yaml', NULL),
 (109, 'ruoyi-file.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '文件服务', NULL, NULL, 'yaml', NULL),
 (110, 'sentinel-ruoyi-gateway.json', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '限流策略', NULL, NULL, 'json', NULL),
-(111, 'ruoyi-xxl-job-admin.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务控制台', NULL, NULL, 'yaml', NULL);
+(111, 'ruoyi-xxl-job-admin.yml', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务控制台', NULL, NULL, 'yaml', NULL),
+(112, 'seata-server.properties', 'DEFAULT_GROUP', '# 将项目路径:config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', 'seata配置文件', NULL, NULL, 'properties', NULL);
 
 /******************************************/
 /*   表名称 = config_info_aggr   */

+ 18 - 2
sql/ry_seata.sql

@@ -51,15 +51,31 @@ CREATE TABLE IF NOT EXISTS `branch_table`
 CREATE TABLE IF NOT EXISTS `lock_table`
 (
     `row_key`        VARCHAR(128) NOT NULL,
-    `xid`            VARCHAR(96),
+    `xid`            VARCHAR(128),
     `transaction_id` BIGINT,
     `branch_id`      BIGINT       NOT NULL,
     `resource_id`    VARCHAR(256),
     `table_name`     VARCHAR(32),
     `pk`             VARCHAR(36),
+    `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
     `gmt_create`     DATETIME,
     `gmt_modified`   DATETIME,
     PRIMARY KEY (`row_key`),
+    KEY `idx_status` (`status`),
     KEY `idx_branch_id` (`branch_id`)
 ) ENGINE = InnoDB
-  DEFAULT CHARSET = utf8mb4;
+  DEFAULT CHARSET = utf8;
+
+CREATE TABLE IF NOT EXISTS `distributed_lock`
+(
+    `lock_key`       CHAR(20) NOT NULL,
+    `lock_value`     VARCHAR(20) NOT NULL,
+    `expire`         BIGINT,
+    primary key (`lock_key`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
+INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
+INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
+INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);