SEATA 配置

使用 nacos 做为配置中心配置 SEATA

当前 SEATA 版本: 1.4.1

TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

配置参数

参数文档

config.txt
  1. transport.type=TCP
  2. transport.server=NIO
  3. transport.heartbeat=true
  4. transport.enableClientBatchSendRequest=false
  5. transport.threadFactory.bossThreadPrefix=NettyBoss
  6. transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
  7. transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
  8. transport.threadFactory.shareBossWorker=false
  9. transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
  10. transport.threadFactory.clientSelectorThreadSize=1
  11. transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
  12. transport.threadFactory.bossThreadSize=1
  13. transport.threadFactory.workerThreadSize=default
  14. transport.shutdown.wait=3
  15. service.vgroupMapping.app-server-tx-group=default
  16. service.default.grouplist=127.0.0.1:8091
  17. service.enableDegrade=false
  18. service.disableGlobalTransaction=false
  19. client.rm.asyncCommitBufferLimit=10000
  20. client.rm.lock.retryInterval=10
  21. client.rm.lock.retryTimes=30
  22. client.rm.lock.retryPolicyBranchRollbackOnConflict=true
  23. client.rm.reportRetryCount=5
  24. client.rm.tableMetaCheckEnable=false
  25. client.rm.sqlParserType=druid
  26. client.rm.reportSuccessEnable=false
  27. client.rm.sagaBranchRegisterEnable=false
  28. client.tm.commitRetryCount=5
  29. client.tm.rollbackRetryCount=5
  30. client.tm.defaultGlobalTransactionTimeout=60000
  31. client.tm.degradeCheck=false
  32. client.tm.degradeCheckAllowTimes=10
  33. client.tm.degradeCheckPeriod=2000
  34. store.mode=db
  35. store.file.dir=file_store/data
  36. store.file.maxBranchSessionSize=16384
  37. store.file.maxGlobalSessionSize=512
  38. store.file.fileWriteBufferCacheSize=16384
  39. store.file.flushDiskMode=async
  40. store.file.sessionReloadReadSize=100
  41. store.db.datasource=druid
  42. store.db.dbType=mysql
  43. store.db.driverClassName=com.mysql.jdbc.Driver
  44. store.db.url=url
  45. store.db.user=root
  46. store.db.password=123456
  47. store.db.minConn=5
  48. store.db.maxConn=30
  49. store.db.globalTable=global_table
  50. store.db.branchTable=branch_table
  51. store.db.queryLimit=100
  52. store.db.lockTable=lock_table
  53. store.db.maxWait=5000
  54. store.redis.host=127.0.0.1
  55. store.redis.port=6379
  56. store.redis.maxConn=10
  57. store.redis.minConn=1
  58. store.redis.database=10
  59. store.redis.password=null
  60. store.redis.queryLimit=100
  61. server.recovery.committingRetryPeriod=1000
  62. server.recovery.asynCommittingRetryPeriod=1000
  63. server.recovery.rollbackingRetryPeriod=1000
  64. server.recovery.timeoutRetryPeriod=1000
  65. server.maxCommitRetryTimeout=-1
  66. server.maxRollbackRetryTimeout=-1
  67. server.rollbackRetryTimeoutUnlockEnable=false
  68. client.undo.dataValidation=true
  69. client.undo.logSerialization=jackson
  70. client.undo.onlyCareUpdateColumns=true
  71. server.undo.logSaveDays=7
  72. server.undo.logDeletePeriod=86400000
  73. client.undo.logTable=undo_log
  74. client.log.exceptionRate=100
  75. transport.serialization=seata
  76. transport.compressor=none
  77. metrics.enabled=false
  78. metrics.registryType=compact
  79. metrics.exporterList=prometheus
  80. metrics.exporterPrometheusPort=9898

nacos bash 脚本

参考 SEATA github 配置说明

nacos-config.sh

  1. while getopts ":h:p:g:t:u:w:" opt
  2. do
  3. case $opt in
  4. h)
  5. host=$OPTARG
  6. ;;
  7. p)
  8. port=$OPTARG
  9. ;;
  10. g)
  11. group=$OPTARG
  12. ;;
  13. t)
  14. tenant=$OPTARG
  15. ;;
  16. u)
  17. username=$OPTARG
  18. ;;
  19. w)
  20. password=$OPTARG
  21. ;;
  22. ?)
  23. echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] "
  24. exit 1
  25. ;;
  26. esac
  27. done
  28. if [[ -z ${host} ]]; then
  29. host=localhost
  30. fi
  31. if [[ -z ${port} ]]; then
  32. port=8848
  33. fi
  34. if [[ -z ${group} ]]; then
  35. group="SEATA_GROUP"
  36. fi
  37. if [[ -z ${tenant} ]]; then
  38. tenant=""
  39. fi
  40. if [[ -z ${username} ]]; then
  41. username=""
  42. fi
  43. if [[ -z ${password} ]]; then
  44. password=""
  45. fi
  46. nacosAddr=$host:$port
  47. contentType="content-type:application/json;charset=UTF-8"
  48. echo "set nacosAddr=$nacosAddr"
  49. echo "set group=$group"
  50. failCount=0
  51. tempLog=$(mktemp -u)
  52. function addConfig() {
  53. curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$1&group=$group&content=$2&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null
  54. if [[ -z $(cat "${tempLog}") ]]; then
  55. echo " Please check the cluster status. "
  56. exit 1
  57. fi
  58. if [[ $(cat "${tempLog}") =~ "true" ]]; then
  59. echo "Set $1=$2 successfully "
  60. else
  61. echo "Set $1=$2 failure "
  62. (( failCount++ ))
  63. fi
  64. }
  65. count=0
  66. for line in $(cat config.txt | sed s/[[:space:]]//g); do
  67. (( count++ ))
  68. key=${line%%=*}
  69. value=${line#*=}
  70. addConfig "${key}" "${value}"
  71. done
  72. echo "========================================================================="
  73. echo " Complete initialization parameters, total-count:$count , failure-count:$failCount "
  74. echo "========================================================================="
  75. if [[ ${failCount} -eq 0 ]]; then
  76. echo " Init nacos config finished, please start seata-server. "
  77. else
  78. echo " init nacos config fail. "
  79. fi

同步 config 配置到 nacos

进入 TC 服务器

  • 新建文件夹 seata-config

  • 进入 seata-config

  • 新建 config.txt 文件并复制配置参数到 config.txt 文件中

  • 新建 nacos-config.sh 文件,同时复制 nacos bash 脚本到 nacos-config.sh 中

  • 使用以下命令同步配置参数到 nacos

    1. bash nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -t 3a2aea46-07c6-4e21-9a1e-8946cde9e2b3 -u nacos -w nacos

    得到输出

    1. set nacosAddr=127.0.0.1:8848
    2. set group=SEATA_GROUP
    3. Set transport.type=TCP successfully
    4. Set transport.server=NIO successfully
    5. .
    6. .
    7. .
    8. =========================================================================
    9. Complete initialization parameters, total-count:80 , failure-count:0
    10. =========================================================================
    11. Init nacos config finished, please start seata-server.

使用 docker 部署 SEATA

Docker 部署 SEATA 官方文档

进入 TC 服务器,并进入 seat-config 文件夹

  • 新建 registry.conf 文件,并添加以下内容,registry 配置参考

    registry.conf
    1. registry {
    2. # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
    3. type = "nacos"
    4. nacos {
    5. application = "seata-server"
    6. group = "SEATA_GROUP"
    7. serverAddr = "127.0.0.1"
    8. namespace = "3a2aea46-07c6-4e21-9a1e-8946cde9e2b3"
    9. cluster = "default"
    10. }
    11. }
    12. config {
    13. # file、nacos 、apollo、zk、consul、etcd3、springCloudConfig
    14. type = "nacos"
    15. nacos {
    16. serverAddr = "127.0.0.1"
    17. namespace = "3a2aea46-07c6-4e21-9a1e-8946cde9e2b3"
    18. group = "SEATA_GROUP"
    19. username = "nacos"
    20. password = "nacos"
    21. }
    22. }
  • 新建 file.conf 文件并添加以下内容(可选,可通过 nacos 读取)

    file.conf
    1. transport {
    2. # tcp udt unix-domain-socket
    3. type = "TCP"
    4. #NIO NATIVE
    5. server = "NIO"
    6. #enable heartbeat
    7. heartbeat = true
    8. # the client batch send request enable
    9. enableClientBatchSendRequest = true
    10. #thread factory for netty
    11. threadFactory {
    12. bossThreadPrefix = "NettyBoss"
    13. workerThreadPrefix = "NettyServerNIOWorker"
    14. serverExecutorThread-prefix = "NettyServerBizHandler"
    15. shareBossWorker = false
    16. clientSelectorThreadPrefix = "NettyClientSelector"
    17. clientSelectorThreadSize = 1
    18. clientWorkerThreadPrefix = "NettyClientWorkerThread"
    19. # netty boss thread size,will not be used for UDT
    20. bossThreadSize = 1
    21. #auto default pin or 8
    22. workerThreadSize = "default"
    23. }
    24. shutdown {
    25. # when destroy server, wait seconds
    26. wait = 3
    27. }
    28. serialization = "seata"
    29. compressor = "none"
    30. }
    31. service {
    32. #transaction service group mapping
    33. vgroupMapping.my_test_tx_group = "default"
    34. #only support when registry.type=file, please don't set multiple addresses
    35. default.grouplist = "127.0.0.1:8091"
    36. #degrade, current not support
    37. enableDegrade = false
    38. #disable seata
    39. disableGlobalTransaction = false
    40. }
    41. client {
    42. rm {
    43. asyncCommitBufferLimit = 10000
    44. lock {
    45. retryInterval = 10
    46. retryTimes = 30
    47. retryPolicyBranchRollbackOnConflict = true
    48. }
    49. reportRetryCount = 5
    50. tableMetaCheckEnable = false
    51. reportSuccessEnable = false
    52. }
    53. tm {
    54. commitRetryCount = 5
    55. rollbackRetryCount = 5
    56. }
    57. undo {
    58. dataValidation = true
    59. logSerialization = "jackson"
    60. logTable = "undo_log"
    61. }
    62. log {
    63. exceptionRate = 100
    64. }
    65. }
  • 运行 docker 命令

    • 注意: 当在 config.txt 中配置 store.mode=db 时,需要在配置的数据库连接中初始化表 global_tablebranch_tablelock_tablesql 传送门
    1. docker run -d --name seata-server \
    2. --net=host \
    3. -p 8091:8091 \
    4. -e SEATA_CONFIG_NAME=file:/root/seata-config/registry \
    5. -v /root/seata-config:/root/seata-config \
    6. seataio/seata-server:1.4.1

    挂载目录为 TC 服务器配置目录。

TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

例子:业务聚合服务

  • SEATA 包引入。pom 配置如下,当使用 spring-cloud-starter-openfeign 包时,需要移除 spring-cloud-starter-openfeign 包,spring-cloud-starter-alibaba-seata 中已经包含了 spring-cloud-starter-openfeign ,再次引入可能导致包冲突。

    pom.xml
    1. <dependency>
    2. <groupId>io.seata</groupId>
    3. <artifactId>seata-spring-boot-starter</artifactId>
    4. <version>1.4.1</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>com.alibaba.cloud</groupId>
    8. <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    9. <version>2.2.1.RELEASE</version>
    10. <exclusions>
    11. <exclusion>
    12. <groupId>io.seata</groupId>
    13. <artifactId>seata-spring-boot-starter</artifactId>
    14. </exclusion>
    15. <exclusion>
    16. <groupId>io.seata</groupId>
    17. <artifactId>seata-all</artifactId>
    18. </exclusion>
    19. </exclusions>
    20. </dependency>
  • 添加 registry.conf。在工程中 resource 目录下添加如下内容

    registry.conf
    1. registry {
    2. # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
    3. type = "nacos"
    4. nacos {
    5. application = "seata-server"
    6. serverAddr = "127.0.0.1:8848"
    7. namespace = "3a2aea46-07c6-4e21-9a1e-8946cde9e2b3"
    8. cluster = "default"
    9. username = "nacos"
    10. password = "nacos"
    11. }
    12. }
    13. config {
    14. # file、nacos 、apollo、zk、consul、etcd3、springCloudConfig
    15. type = "nacos"
    16. nacos {
    17. serverAddr = "127.0.0.1:8848"
    18. namespace = "3a2aea46-07c6-4e21-9a1e-8946cde9e2b3"
    19. group = "SEATA_GROUP"
    20. username = "nacos"
    21. password = "nacos"
    22. }
    23. }
  • 配置 bootstrap.properties,添加配置,内容如下,seata.tx-service-groupnamespace 改为对应的值

    bootstrap.properties
    1. ...
    2. seata.tx-service-group=app-server-tx-group
    3. seata.config.type=nacos
    4. seata.config.nacos.server-addr=127.0.0.1:8848
    5. seata.config.nacos.namespace=3a2aea46-07c6-4e21-9a1e-8946cde9e2b3
    6. seata.config.nacos.group=SEATA_GROUP

在 TM 中通过 @GlobalTransactional 开启全局异常,示例代码:


  1. @GlobalTransactional
  2. @GetMapping({"create"})
  3. public String create(String name,Integer age) {
  4. ...
  5. return "创建成功";
  6. }

RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

例子:被调用服务。

  • 配置 bootstrap.properties,添加配置,内容如下,seata.tx-service-groupnamespace 改为对应的值

    bootstrap.properties
    1. ...
    2. seata.tx-service-group=app-server-tx-group
    3. seata.config.type=nacos
    4. seata.config.nacos.server-addr=127.0.0.1:8848
    5. seata.config.nacos.namespace=3a2aea46-07c6-4e21-9a1e-8946cde9e2b3
    6. seata.config.nacos.group=SEATA_GROUP
  • 对需要做回滚的业务标记 @Transactional(rollbackFor = Exception.class)

  • 如果配置了全局异常处理,使用 SEATA API 发起事务回滚

    1. @ExceptionHandler(value = Exception.class)
    2. @ResponseBody
    3. public String exceptionHandler(Exception e) {
    4. ...
    5. try {
    6. String xid = RootContext.getXID();
    7. if (StringUtils.isNotEmpty(xid)) {
    8. GlobalTransactionContext.reload(RootContext.getXID()).rollback();
    9. }
    10. } catch (TransactionException transactionException) {
    11. transactionException.printStackTrace();
    12. log.error("===TransactionException==={}", transactionException.getMessage());
    13. }
    14. return e.getMessage();
    15. }

    或者通过 AOP 全局处理回滚


    1. /**
    2. * @author Zhang_Xiang
    3. * @since 2021/2/22 17:36:16
    4. */
    5. @Aspect
    6. @Component
    7. @Slf4j
    8. public class TxAspect {
    9. @Pointcut("execution(public * *(..))")
    10. public void publicMethod() {
    11. }
    12. @Pointcut("within(com.*.service.impl..*)")
    13. private void services() {
    14. }
    15. @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
    16. private void transactional() {
    17. }
    18. @Pointcut("within(com.*.webapi.controller..*)")
    19. private void actions() {
    20. }
    21. @Pointcut("@annotation(org.springframework.web.bind.annotation.ExceptionHandler))")
    22. private void validatedException() {
    23. }
    24. @Before(value = "validatedException()")
    25. public void beforeValidate(JoinPoint joinPoint) throws TransactionException {
    26. Object[] args = joinPoint.getArgs();
    27. if (args == null || args.length == 0) {
    28. return;
    29. }
    30. Exception e = (Exception) args[0];
    31. if (e instanceof MethodArgumentNotValidException || e instanceof BindException || e instanceof
    32. ConstraintViolationException) {
    33. globalRollback();
    34. }
    35. }
    36. @AfterThrowing(throwing = "e", pointcut = "publicMethod()&&services()&&transactional()")
    37. public void doRecoveryMethods(Throwable e) throws TransactionException {
    38. log.info("===method throw===:{}", e.getMessage());
    39. globalRollback();
    40. }
    41. @AfterReturning(value = "publicMethod()&&actions()", returning = "result")
    42. public void afterReturning(RestResponse<?> result) throws TransactionException {
    43. log.info("===method finished===:{}", result);
    44. if (result.isFail()) {
    45. globalRollback();
    46. }
    47. }
    48. //region private methods
    49. private void globalRollback() throws TransactionException {
    50. if (!StringUtils.isBlank(RootContext.getXID())) {
    51. log.info("===xid===:{}", RootContext.getXID());
    52. GlobalTransactionContext.reload(RootContext.getXID()).rollback();
    53. }
    54. }
    55. //endregion
    56. }

分布式事务 SEATA-1.4.1 AT模式 配合NACOS 应用的更多相关文章

  1. 分布式事务 Seata Saga 模式首秀以及三种模式详解 | Meetup#3 回顾

    https://mp.weixin.qq.com/s/67NvEVljnU-0-6rb7MWpGw 分布式事务 Seata Saga 模式首秀以及三种模式详解 | Meetup#3 回顾 原创 蚂蚁金 ...

  2. 分布式事务(Seata) 四大模式详解

    前言 在上一节中我们讲解了,关于分布式事务和seata的基本介绍和使用,感兴趣的小伙伴可以回顾一下<别再说你不知道分布式事务了!> 最后小农也说了,下期会带给大家关于Seata中关于sea ...

  3. 阿里分布式事务seata入门(采坑)

    1. 阿里分布式事务seata入门(采坑) 1.1. 前言 seata是feascar改名而来,这是阿里在19年年初开源出来的分布式事务框架,当初刚出来的时候就想研究下了,一直拖到了现在,目前是0.8 ...

  4. 分布式事务(Seata)原理 详解篇,建议收藏

    前言 在之前的系列中,我们讲解了关于Seata基本介绍和实际应用,今天带来的这篇,就给大家分析一下Seata的源码是如何一步一步实现的.读源码的时候我们需要俯瞰起全貌,不要去扣一个一个的细节,这样我们 ...

  5. SpringCloud系列之集成分布式事务Seata应用篇

    目录 前言 项目版本 项目说明 Seata服务端部署 Seata客户端集成 cloud-web module-order module-cart module-goods module-wallet ...

  6. 出席分布式事务Seata 1.0.0 GA典礼

    前言 图中那个红衣服的就是本人 什么是分布式事务 分布式事务就是指事务的参与者.支持事务的服务器.资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上. 简单的说,就是一次大的操作由不同的小 ...

  7. 微服务开发的最大痛点-分布式事务SEATA入门简介

    前言 在微服务开发中,存在诸多的开发痛点,例如分布式事务.全链路跟踪.限流降级和服务平滑上下线等.而在这其中,分布式事务是最让开发者头痛的.那分布式事务是什么呢? 分布式事务就是指事务的参与者.支持事 ...

  8. SpringCloud整合分布式事务Seata 1.4.1 支持微服务全局异常拦截

    项目依赖 SpringBoot 2.5.5 SpringCloud 2020.0.4 Alibaba Spring Cloud 2021.1 Mybatis Plus 3.4.0 Seata 1.4. ...

  9. spring boot:使用分布式事务seata(druid 1.1.23 / seata 1.3.0 / mybatis / spring boot 2.3.2)

    一,什么是seata? Seata:Simpe Extensible Autonomous Transcaction Architecture, 是阿里中间件开源的分布式事务解决方案. 前身是阿里的F ...

随机推荐

  1. java HashMap and HashMultimap 区别

    http://stackoverflow.com/questions/19222029/what-is-difference-between-hashmap-and-hashmultimap The ...

  2. DEDECMS:删除DEDE自带的织梦链方法

    在include/taglib/flinktype.lib.php里删除掉如下代码: $dedecms = false; $dedecms->id = 999; $dedecms->typ ...

  3. 【Java】构造方法

    成员变量声明时初始化和构造方法中初始化的区别 声明时为成员变量赋值,那每次创建这个类的对象都是同一个值. 构造方法初始化,每次创建对象时可以为每一个对象赋不同的值(此时要通过有参构造). 无返回值类型 ...

  4. linux开发各种I/O操作简析,以及select、poll、epoll机制的对比

    作者:良知犹存 转载授权以及围观:欢迎添加微信公众号:羽林君 IO 概念区分 四个相关概念: 同步(Synchronous) 异步( Asynchronous) 阻塞( Blocking ) 非阻塞( ...

  5. poj 2007 凸包构造和极角排序输出(模板题)

    Scrambled Polygon Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10841   Accepted: 508 ...

  6. Codeforces Round #602 Div2 D1. Optimal Subsequences (Easy Version)

    题意:给你一个数组a,询问m次,每次返回长度为k的和最大的子序列(要求字典序最小)的pos位置上的数字. 题解:和最大的子序列很简单,排个序就行,但是题目要求字典序最小,那我们在刚开始的时候先记录每个 ...

  7. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 A.牛牛爱奇数 (模拟)

    题意:有一组数,每次将所有相等的偶数/2,求最少操作多少次使得所有数变成奇数. 题解:用桶标记,将所有不同的偶数取出来,然后写个while模拟统计一下次数就行. 代码: class Solution ...

  8. Eazfuscator.NET(.net混淆工具)

    软件功能 调试支持: 在你的程序集被Eazfuscator.NET混淆后,它不会成为不可调试混乱的砖块.你总是可以得到一个行号,出现未处理的异常,查看可读的堆栈跟踪,甚至附加调试器来遍历你的模糊代码. ...

  9. leetcode31 下一个排列 字典序

    数字的字典序就是比大小 先想几个例子  123_>132  1243-> 1324 ,12453-> 12534 1.不可排的序列就是降序序列 2.两个相同长度的串比大小,前面相同, ...

  10. leetcode 12 整数转罗马数字 贪心

    额,连着两个贪心? 这是局部最优问题:能用大"罗马数表示"就不会用小的. 先构造出所有基础罗马数,然后从大到小比较 因为比较的只有1000,900,...有限并有些麻烦,构造tab ...