springcloud+nacos集成seata

springcloud集成seata

ps:本文是在已有nacos的基础上集成seata

版本(版本好像也没影响0.o):
Linux版本:ubuntu20.04
springcloud版本:Hoxton.SR8
seata版本:seata-server-1.3.0

一、服务端:文件准备

1、先去下载seata的Linux压缩包,官网:https://github.com/seata/seata
解压缩:tar -zvxf seata-1.3.0.tar.gz
压缩后的文件目录是这样的(ps:一开始下载错了,打开都是Java文件。。。)
![压缩后的文件目录](https://img-blog.csdnimg.cn/f0acf1aa6d98482fb6848f4f01245f13.pngseata目录

2、nacos-config.sh内容(建议直接去github复制,我一开始也是复制别人的,结果可能是因为复制粘贴的格式问题,运行不了,如下):
https://github.com/seata/seata/blob/develop/script/config-center/nacos/nacos-config.sh

#!/bin/sh
# Copyright 1999-2019 Seata.io Group.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at、
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

while getopts ":h:p:g:t:u:w:" opt
do
  case $opt in
  h)
    host=$OPTARG
    ;;
  p)
    port=$OPTARG
    ;;
  g)
    group=$OPTARG
    ;;
  t)
    tenant=$OPTARG
    ;;
  u)
    username=$OPTARG
    ;;
  w)
    password=$OPTARG
    ;;
  ?)
    echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] "
    exit 1
    ;;
  esac
done

if [ -z ${host} ]; then
    host=nacos的IP
fi
if [ -z ${port} ]; then
    port=nacos端口
fi
if [ -z ${group} ]; then
    group="SEATA_GROUP"
fi
if [ -z ${tenant} ]; then
    tenant=""
fi
if [ -z ${username} ]; then
    username="nacos"
fi
if [ -z ${password} ]; then
    password="nacos"
fi

nacosAddr=$host:$port
contentType="content-type:application/json;charset=UTF-8"

echo "set nacosAddr=$nacosAddr"
echo "set group=$group"

urlencode() {
  length="${#1}"
  i=0
  while [ $length -gt $i ]; do
    char="${1:$i:1}"
    case $char in
    [a-zA-Z0-9.~_-]) printf $char ;;
    *) printf '%%%02X' "'$char" ;;
    esac
    i=`expr $i + 1`
  done
}

failCount=0
tempLog=$(mktemp -u)
function addConfig() {
  dataId=`urlencode $1`
  content=`urlencode $2`
  curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$dataId&group=$group&content=$content&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null
  if [ -z $(cat "${tempLog}") ]; then
    echo " Please check the cluster status. "
    exit 1
  fi
  if [ "$(cat "${tempLog}")" == "true" ]; then
    echo "Set $1=$2 successfully "
  else
    echo "Set $1=$2 failure "
    failCount=`expr $failCount + 1`
  fi
}

count=0
COMMENT_START="#"
#这里注意你的config.txt的路径,我这里多了个seata目录
for line in $(cat $(dirname "$PWD")/seata/config.txt | sed s/[[:space:]]//g); do
    if [[ "$line" =~ ^"${COMMENT_START}".*  ]]; then
      continue
    fi
    count=`expr $count + 1`
	  key=${line%%=*}
    value=${line#*=}
	  addConfig "${key}" "${value}"
done

echo "========================================================================="
echo " Complete initialization parameters,  total-count:$count ,  failure-count:$failCount "
echo "========================================================================="

if [ ${failCount} -eq 0 ]; then
	echo " Init nacos config finished, please start seata-server. "
else
	echo " init nacos config fail. "
fi

3、config.txt内容:

transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3

#这里需要指定你的服务和后面的yml文件对应,我目前就2个服务,所以配置了
#service.vgroupMapping.luoz-auth和service.vgroupMapping.luoz-shenwan,这2行记得删除,否则运行不了
service.vgroupMapping.seata-account-service-fescar-service-group=default
service.vgroupMapping.luoz-auth=default
service.vgroupMapping..luoz-shenwan=default

service.default.grouplist=部署seata的IP:端口
service.enableDegrade=false
service.disableGlobalTransaction=false

client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000

store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://数据库IP:端口/seata?useUnicode=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
store.db.user=数据库账号
store.db.password=数据库密码
store.db.minConn=3
store.db.maxConn=10
store.db.globalTable=global_table
store.db.branchTable=branch_table
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

client.undo.dataValidation=true
client.undo.logSerialization=jackson
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

4、在你的数据库中新建一个名字就叫:seata,的数据库,并运行创建表的sql语句
创建表官方地址:https://github.com/seata/seata/blob/develop/script/server/db/mysql.sql
seata数据库表

-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `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`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(96),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

5、进入解压缩的seata文件夹下的conf文件夹,修改下图的2个配置文件
seata配置文件修改

registry.conf配置(我用的是nacos,所以只修改了nacos的配置):

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
    application = "seata-server"
    serverAddr = "http://nacos的IP:端口(注意结尾这里不要加/)"
    group = "SEATA_GROUP"
    namespace = "这里可以指定你的seata服务启动后在nacos的位置,为空默认public"
    cluster = "default"
    username = ""
    password = ""
  }
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"
  }
  redis {
    serverAddr = "localhost:6379"
    db = 0
    password = ""
    cluster = "default"
    timeout = 0
  }
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  consul {
    cluster = "default"
    serverAddr = "127.0.0.1:8500"
  }
  etcd3 {
    cluster = "default"
    serverAddr = "http://localhost:2379"
  }
  sofa {
    serverAddr = "127.0.0.1:9603"
    application = "default"
    region = "DEFAULT_ZONE"
    datacenter = "DefaultDataCenter"
    cluster = "default"
    group = "SEATA_GROUP"
    addressWaitTime = "3000"
  }
  file {
    name = "file.conf"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "file"

  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = ""
    password = ""
  }
  consul {
    serverAddr = "127.0.0.1:8500"
  }
  apollo {
    appId = "seata-server"
    apolloMeta = "http://192.168.1.204:8801"
    namespace = "application"
  }
  zk {
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  etcd3 {
    serverAddr = "http://localhost:2379"
  }
  file {
    name = "file.conf"
  }
}

file.conf配置:


## transaction log store, only used in seata-server
store {
  ## store mode: file、db、redis
  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)/HikariDataSource(hikari) etc.
    datasource = "druid"
    ## mysql/oracle/postgresql/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://你的数据库IP:端口/seata"
    user = "账号"
    password = "密码"
    minConn = 5
    maxConn = 30
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }

  ## redis store property
  #redis {
    #host = "127.0.0.1"
    #port = "6379"
    #password = ""
    #database = "0"
    #minConn = 1
    #maxConn = 10
    #queryLimit = 100
  #}

}

到这里文件上的准备就结束了,下面就是运行配置文件和启动seata服务了

二、服务端:启动配置文件和启动服务

1、启动你的nacos-config.sh,启动命令:

sh ./nacos-config.sh -t 7fd2e86d-f02a-4ada-a78b-93816b5abdeb (我用这种会报错,所以改用下面的)
bash ./nacos-config.sh -t 7fd2e86d-f02a-4ada-a78b-93816b5abdeb
#可选参数:
-h 你要写入的nacos主机IP,默认localhost
-p 你要写入的nacos主机端口,默认8848
-group 你要写入的配置所属的组,默认SEATA_GROUP
-t nacos分支uuid

我这里之前报错:./nacos-config.sh: 行 88: 未预期的符号“|”附近有语法错误 ./nacos-config.sh: 行 88: `for line in $PWD/config.txt | se
就是因为nacos-config.sh文件里的内容是我复制别人的,不是官方的。再不行就在windows系统下使用notepad++编辑该sh文件,双击文件右下角编码区域选择"转换为UNIX格式"。再再不行就百度吧。。。
运行成功之后:在这里插入图片描述
nacos截图(出现好多配置文件):
在这里插入图片描述

接着启动seata服务,进入bin目录
Seata的启动命令参数说明
完整的启动命令如下:

sh ./bin/seata-server.sh -p 8091 -h 127.0.0.1 -m file -n 1 -e dev

-h : 指定在注册中心注册的IP;不指定时获取当前的 IP,外部访问部署在云环境和容器中的server建议指定;
-p : 指定 server 启动的端口; 默认为 8091;
-m : 事务日志存储方式;支持file,db,redis,默认为file;注意redis需seata-server 1.3版本及以上;
-n : 用于指定seata-server节点ID;如 1,2,3…, 默认为 1;
-e : 指定 seata-server 运行环境;如:dev, test 等, 服务启动时会使用 registry-dev.conf 这样的配置;
因此单机版部署使用的完成命令如下:

sh ./bin/seata-server.sh -p 8091 -h 127.0.0.1  -m file

这样启动之后后一直在seata启动页面,后台运行用nohup

nohup ./bin/seata-server.sh -p 8091 -h 127.0.0.1  -m file >log.out 2>1 &

这里要让防火墙开放seata的端口,用阿里云的话还要开放规则,否则连不上数据库报错
在这里插入图片描述
启动成功之后,seata服务会注册在nacos里
在这里插入图片描述

三、客户端

1、引入seata依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <version>2.2.2.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>

2、每一个服务的application.yml文件配置如下代码(我这个服务是luoz-shenwan,所以 tx-service-group: luoz-shenwan,其他的服务对应其他的 tx-service-group),另一个就不贴了

spring:
  cloud:
    alibaba:
      seata:
        enabled: true
        application-id: seata-server #nacos中seata服务端的注册名称
        enable-auto-data-source-proxy: true    #开启数据库自动代理
        tx-service-group: luoz-shenwan #这里填写上传config.txt时对应此工程的vgroupMapping配置

3、最后在你的启动类上加上:@EnableSeataSpringConfig注解,这样就可以使用了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,关于这个问题,我可以提供一些参考资料。首先,Spring Cloud是一个基于Spring框架的微服务架构开发工具包,提供丰富的开箱即用的组件和框架,可以较为方便地实现微服务的开发、部署和管理。而Nacos是阿里巴巴开源的一个面向服务中心的动态服务发现、配置管理和服务治理平台,可以提供服务注册与发现、配置管理、流量管理、域名解析等功能。Seata是阿里巴巴开源的一个分布式事务解决方案,可以提供数据源代理、事务协调、幂等性设计等功能,用于解决微服务架构下的分布式事务问题。 在Spring Cloud中集成NacosSeata,需要进行如下步骤: 1. 引入相应的依赖,例如在pom.xml文件中添加如下依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.4.2</version> </dependency> ``` 其中,spring-cloud-starter-alibaba-nacos-config和spring-cloud-starter-alibaba-nacos-discovery是Nacos的客户端依赖,seata-spring-boot-starter是Seata的客户端依赖。 2. 配置Nacos的地址和Seata的事务配置,例如在application.yml文件中添加如下配置: ```yaml spring: cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yml seata: tx-service-group: my_test_tx_group application-id: ${spring.application.name} enabled: true mybatis: configuration: # ... seata: enabled: true application-id: ${spring.application.name} tx-service-group: my_test_tx_group config: transport: enabled: true type: TCP server: localhost:8091 heartbeat: true heartbeat.interval.ms: 5000 disableHeartbeatChecking: true client-selector: rnd client-list: 127.0.0.1:8091 shutdown.timeout.ms: 5000 registry: type: Nacos nacos: application: ${spring.application.name} serverAddr: localhost:8848 namespace: public ``` 其中,Nacos的地址和Seata的事务配置可以根据具体情况自行修改。 3. 配置完毕后,就可以使用Nacos作为Spring Cloud的注册中心和配置中心,使用Seata来解决分布式事务问题了。 以上是关于如何在Spring Cloud中集成NacosSeata的简要介绍,希望能够帮助到你。如果你还有其他问题,可以继续向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值