seata-1.2.0解决SpringCloud分布式事务 nacos注册中心 seata-1.2.0踩过的坑

seata-1.3.0传送门

  • seata-1.3.0解决SpringCloud分布式事务 nacos注册中心:https://blog.csdn.net/sinat_38670641/article/details/108237920

初衷

头痛于分布式事务的解决,找了一下相关的开源解决方案,主要有两个:

  • tx-lcn
  • seata

因为tx-lcn好像没有解决资金问题,似乎有停止维护的趋势,所以本人选择了seata
然后在seata整合SpringCloud Nacos的过程中踩了太多的坑,网上大多数博客使用版本都比较靠前,v1.0.0起以后的版本压缩包中缺少部分执行文件。所以想把自己踩过的坑写一下,希望能帮到有需要的同学,为大家节省一些时间。

Seata 是什么?

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

相关链接

  • 官网:https://seata.io/zh-cn/
  • seata-server下载链接:https://github.com/seata/seata/releases/tag/v1.2.0
  • seata-server配置官方相关文档:https://github.com/seata/seata-samples/tree/master/springcloud-nacos-seata
  • 官方demo:https://github.com/seata/seata-samples/tree/master

启动Nacos

  • 下载nacos客户端:https://github.com/alibaba/nacos/releases

  • 配置nacos数据源

    • 创建数据库:nacos-config
    • 执行sql脚本:/conf/nacos-mysql.sql
    • 修改nacos配置文件:/conf/application.properties
      # 数据库类型
      spring.datasource.platform=mysql
      # 数据源数量
      db.num=1
      # 数据源1
      db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
      # 数据源2
      #db.url.1=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
      db.user=root
      db.password=root
      
  • 启动nacos客户端

    • Windows:/bin/startup.cmd
    • Linux:/bin/startup.sh
  • nacos控制台:http://127.0.0.1:8848/nacos/index.html#/login

    • 账户:nacos
    • 密码:nacos

配置seata-server并启动

  • 修改conf/registry.conf 配置

    registry {
      # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
      type = "nacos"
    
      nacos {
        # serverAddr 不需要带http://,配置nacos注册中心所以服务器ip,本人是本机启动的nacos
        serverAddr = "127.0.0.1"
        # nacos工作台中的命名空间,使用【public(保留空间)】即可
        namespace = "public"
        cluster = "default"
      }
    }
    config {
      # file、nacos 、apollo、zk、consul、etcd3
      type = "nacos"
      nacos {
        serverAddr = "127.0.0.1"
        namespace = "public"
        cluster = "default"
      }
    }
    
  • 修改conf/file.conf配置

    store {
      ## store mode: file、db
      # 修改为 db
      mode = "db"
    
      ## file store property
      file {
        ## store location dir
        dir = "sessionStore"
        # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
        maxBranchSessionSize = 16384
        # globe session size , if exceeded throws exceptions
        maxGlobalSessionSize = 512
        # file buffer size , if exceeded allocate new buffer
        fileWriteBufferCacheSize = 16384
        # when recover batch read size
        sessionReloadReadSize = 100
        # async, sync
        flushDiskMode = async
      }
    
      ## database store property
      db {
        ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
        datasource = "druid"
        ## mysql/oracle/postgresql/h2/oceanbase etc.
        dbType = "mysql"
        driverClassName = "com.mysql.jdbc.Driver"
        # 修改配置的数据库链接,数据库账号密码
        url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC"
        user = "root"
        password = "root"
        minConn = 5
        maxConn = 30
        globalTable = "global_table"
        branchTable = "branch_table"
        lockTable = "lock_table"
        queryLimit = 100
        maxWait = 5000
      }
    }
    
  • 配置seata数据库,v1.0.0以下版本提供conf/db_store.sql脚本,v1.0.0(包括v1.0.0)版本起压缩包不提供,此处大坑。附上sql脚本

    -- the table to store GlobalSession data
    drop table if exists `global_table`;
    create table `global_table` (
      `xid` varchar(128)  not null,
      `transaction_id` bigint,
      `status` tinyint not null,
      `application_id` varchar(32),
      `transaction_service_group` varchar(32),
      `transaction_name` varchar(128),
      `timeout` int,
      `begin_time` bigint,
      `application_data` varchar(2000),
      `gmt_create` datetime,
      `gmt_modified` datetime,
      primary key (`xid`),
      key `idx_gmt_modified_status` (`gmt_modified`, `status`),
      key `idx_transaction_id` (`transaction_id`)
    );
    
    -- the table to store BranchSession data
    drop table if exists `branch_table`;
    create table `branch_table` (
      `branch_id` bigint not null,
      `xid` varchar(128) not null,
      `transaction_id` bigint ,
      `resource_group_id` varchar(32),
      `resource_id` varchar(256) ,
      `lock_key` varchar(128) ,
      `branch_type` varchar(8) ,
      `status` tinyint,
      `client_id` varchar(64),
      `application_data` varchar(2000),
      `gmt_create` datetime,
      `gmt_modified` datetime,
      primary key (`branch_id`),
      key `idx_xid` (`xid`)
    );
    
    -- the table to store lock data
    drop table if exists `lock_table`;
    create table `lock_table` (
      `row_key` varchar(128) not null,
      `xid` varchar(96),
      `transaction_id` long ,
      `branch_id` long,
      `resource_id` varchar(256) ,
      `table_name` varchar(32) ,
      `pk` varchar(36) ,
      `gmt_create` datetime ,
      `gmt_modified` datetime,
      primary key(`row_key`)
    );
    
  • 修改conf/nacos-config.txt 配置,此处大坑,同上,v1.0.0以下版本提供该文件,v1.0.0(包括v1.0.0)版本起压缩包不提供

    • 附上nacos-config.txt内容

      transport.type=TCP
      transport.server=NIO
      transport.heartbeat=true
      transport.thread-factory.boss-thread-prefix=NettyBoss
      transport.thread-factory.worker-thread-prefix=NettyServerNIOWorker
      transport.thread-factory.server-executor-thread-prefix=NettyServerBizHandler
      transport.thread-factory.share-boss-worker=false
      transport.thread-factory.client-selector-thread-prefix=NettyClientSelector
      transport.thread-factory.client-selector-thread-size=1
      transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread
      transport.thread-factory.boss-thread-size=1
      transport.thread-factory.worker-thread-size=8
      transport.shutdown.wait=3
      service.vgroupMapping.demo-server-group=default
      service.vgroupMapping.demo2-server-group=default
      service.enableDegrade=false
      service.disable=false
      service.max.commit.retry.timeout=-1
      service.max.rollback.retry.timeout=-1
      client.async.commit.buffer.limit=10000
      client.lock.retry.internal=10
      client.lock.retry.times=30
      client.lock.retry.policy.branch-rollback-on-conflict=true
      client.table.meta.check.enable=true
      client.report.retry.count=5
      client.tm.commit.retry.count=1
      client.tm.rollback.retry.count=1
      store.mode=file
      store.file.dir=file_store/data
      store.file.max-branch-session-size=16384
      store.file.max-global-session-size=512
      store.file.file-write-buffer-cache-size=16384
      store.file.flush-disk-mode=async
      store.file.session.reload.read_size=100
      store.db.datasource=dbcp
      store.db.db-type=mysql
      store.db.driver-class-name=com.mysql.jdbc.Driver
      store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC
      store.db.user=root
      store.db.password=root
      store.db.min-conn=1
      store.db.max-conn=3
      store.db.global.table=global_table
      store.db.branch.table=branch_table
      store.db.query-limit=100
      store.db.lock-table=lock_table
      recovery.committing-retry-period=1000
      recovery.asyn-committing-retry-period=1000
      recovery.rollbacking-retry-period=1000
      recovery.timeout-retry-period=1000
      transaction.undo.data.validation=true
      transaction.undo.log.serialization=jackson
      transaction.undo.log.save.days=7
      transaction.undo.log.delete.period=86400000
      transaction.undo.log.table=undo_log
      transport.serialization=seata
      transport.compressor=none
      metrics.enabled=false
      metrics.registry-type=compact
      metrics.exporter-list=prometheus
      metrics.exporter-prometheus-port=9898
      support.spring.datasource.autoproxy=false
      
      

      此处请修改为您需要注册的服务的名称,我这里例子是demo-server-groupdemo2-server-group
      nacos-config.txt配置
      PS:注意!!!!此处有坑,v1.1.0版本之下是vgroup_mapping,v1.1.0版本开始修改为vgroupMapping,高版本没有修改够来会报no service ....seata-1.2.0解决SpringCloud分布式事务 nacos注册中心 seata-1.2.0踩过的坑_第1张图片

    • 也可以从v0.9.0版本的压缩包拉一份出来,但是,请务必注意!!!!如果使用v1.1.0起的版本记得把vgroup_mapping修改为vgroupMapping

  • 使用nacos-config.sh同步配置到nacos此处有坑,同上,v1.0.0以下版本提供该文件,v1.0.0(包括v1.0.0)版本起压缩包不提供

    • 可以从v0.9.0版本的压缩包拉一份出来

    • 附上,也可以自行创建

      #!/usr/bin/env bash
      if [ $# != 1 ]; then
      echo "./nacos-config.sh nacosIp"
      exit -1
      fi
      
      nacosIp=$1
      echo "set nacosIp=$nacosIp"
      error=0
      
      for line in $(cat nacos-config.txt)
      
      do
      
      key=${line%%=*}
      value=${line#*=}
      echo "\r\n set "${key}" = "${value}
      
      result=`curl -X POST "http://$nacosIp:8848/nacos/v1/cs/configs?dataId=$key&group=SEATA_GROUP&content=$value"`
      
      if [ "$result"x == "true"x ]; then
      
        echo "\033[42;37m $result \033[0m"
      
      else
      
        echo "\033[41;37 $result \033[0m"
        let error++
      
      fi
      
      done
      
      
      if [ $error -eq 0 ]; then
      
      echo  "\r\n\033[42;37m init nacos config finished, please start seata-server. \033[0m"
      
      else
      
      echo  "\r\n\033[41;33m init nacos config fail. \033[0m"
      
      fi
      
    • 执行命令, 后面填写nacos的IP地址,我的是本机所以是127.0.0.1

      sh nacos-config.sh 127.0.0.1
      

      windows系统使用Git Bash执行
      seata-1.2.0解决SpringCloud分布式事务 nacos注册中心 seata-1.2.0踩过的坑_第2张图片

      成功后会提示

      init nacos config finished, please start seata-server
      

      nacos配置列表也能查询到相关配置
      seata-1.2.0解决SpringCloud分布式事务 nacos注册中心 seata-1.2.0踩过的坑_第3张图片

  • 启动seata-server

    • windows执行bin/seata-server.bat
    • linux执行bin/seata-server.sh
  • 启动成功nacos服务列表可以查到seata-server服务注册

项目配置

  • 相关jar包

    
    
        com.alibaba.cloud
        spring-cloud-alibaba-seata
        2.1.0.RELEASE
    
    
        io.seata
        seata-all
        1.2.0
    
    

    版本说明:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明

  • 在业务数据库添加undo_log表,v1.0.0以下提供conf/db_undo_log.sql脚本文件,v1.0.0版本起不提供,附上脚本

    drop table `undo_log`;
    CREATE TABLE `undo_log` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `branch_id` bigint(20) NOT NULL,
      `xid` varchar(100) NOT NULL,
      `context` varchar(128) NOT NULL,
      `rollback_info` longblob NOT NULL,
      `log_status` int(11) NOT NULL,
      `log_created` datetime NOT NULL,
      `log_modified` datetime NOT NULL,
      `ext` varchar(100) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    
  • 配置代理数据源

    import com.alibaba.druid.pool.DruidDataSource;
    import io.seata.rm.datasource.DataSourceProxy;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    
    import javax.sql.DataSource;
    
    /**
     * seata分布式事务代理数据源 
    * date:2020-4-30 13:12:33 * * @author MrBUS * @since JDK 1.8 * @version 1.0 */ @Configuration public class SeataConfiguration { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource druidDataSource(){ return new DruidDataSource(); } @Primary @Bean("dataSource") public DataSourceProxy dataSource(DataSource druidDataSource){ return new DataSourceProxy(druidDataSource); } }
  • 启动类开启自动注入:

    @EnableDiscoveryClient
    @EnableAutoConfiguration
    
  • 把配置好的registry.conf文件和file.conf文件放到resources目录下
    seata-1.2.0解决SpringCloud分布式事务 nacos注册中心 seata-1.2.0踩过的坑_第4张图片

  • 配置文件application.yml中配置:

    spring:
    	cloud:
            alibaba:
              seata:
                # nacos-config.txt中配置的service-vgroupMapping
                tx-service-group: demo-server-group
    
  • 在需要开启事务的最上层方法加上@GlobalTransactional(rollbackFor = Exception.class)注解即可
    seata-1.2.0解决SpringCloud分布式事务 nacos注册中心 seata-1.2.0踩过的坑_第5张图片
    seata-1.2.0解决SpringCloud分布式事务 nacos注册中心 seata-1.2.0踩过的坑_第6张图片

总结

以上仅代表个人理解,仅供参考。希望能帮助到有需要的同学。个人技术程度有限,有不对的地方望谅解。

v1.0.0起缺少的文件已打包放在文章中,需要的同学可以免费下载。如果觉得本文有用,请点击一下点赞收藏。谢谢。

  • 缺少文件下载链接:https://download.csdn.net/download/sinat_38670641/12376400

你可能感兴趣的:(java)