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.png
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
-- -------------------------------- 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个配置文件
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注解,这样就可以使用了。