SpringCloud-(七)Seata的部署安装和快速使用

本文最后更新于:January 8, 2023 pm

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

目录

下载地址

官方地址

官方文档

本文使用的是Seata1.6.1版本。

启动

执行:

1
2
cd seata/bin
./seata-server.sh -p 8868 # 指定端口

然后回出现一下内容:

1
2
apm-skywalking not enabled
seata-server is starting, you can check the /Users/dragonone/Desktop/InkM/seata/logs/start.out

然后去对应目录logs下查看日志,查看是否已经启动成功。

导入依赖

在涉及到的服务模块中添加Seata依赖:

1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

添加配置

1
2
3
4
5
6
7
8
9
10
seata:
service:
vgroup-mapping:
# 对事务组进行映射,默认的分组为:应用名称-seata-service-group,将其映射到default集群
core-service-seata-service-group: default
grouplist:
# seata 服务地址
default: localhost:8868
# 指定该事务组名称
# tx-service-group:

core-service-seata-service-group:core-service 是你该服务模块的名称(spring.application.name)。需要注意的是,如果配置了两个配置文件:application-core.yml、bootstrap.yml 并且在两个文件中都设置了名称,那么需要配置成application-core.yml中的,但如果两个名称又不相同,那么就会出现在Nacos中找不到服务,所以,最好两个地方都配置成一样的,或者是只在bootstrap.yml中配置。

自定义事务组

1
2
3
4
5
6
7
8
seata: 
# 事务组的名称,对应service.vgroupMapping.default_tx_group=xxx中配置的default_tx_group
tx-service-group: default_tx_group
# 配置事务组与集群的对应关系
service:
vgroup-mapping:
# default_tx_group为事务组的名称,default为集群名称
default_tx_group: default

另外,最好再加上一个注解(可以不加,根据情况而定,seata1.4好像就必须要加才行):

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableAutoDataSourceProxy
public class CoreApplication {

public static void main(String[] args) {
SpringApplication.run(CoreApplication.class, args);
}

}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Autowired
private UserInfoService userInfoService;

@Autowired
private UserInfoMapper userInfoMapper;

@RequestMapping("/seata")
@GlobalTransactional // 开启事务
public Object testSeata() {
UserInfo temp1 = new UserInfo();
temp1.setPassword("1");
temp1.setUserName("a");
userInfoMapper.insert(temp1);
try {
int i = 2 / 0;
} catch (Exception e) {
throw new BizRuntimeException(BizErrors.E1001);
}
UserInfo temp2 = new UserInfo();
temp2.setPassword("2");
temp2.setUserName("b");
userInfoMapper.insert(temp2);
return new JSONObject()
.fluentPut("flag", "ok")
;
}

添加Seata表

官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
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;

📢注意:每个服务对应的数据库里面都需要添加这个表,如果都使用的同一个表,则添加一个张表即可。

然后访问接口,查看数据是否添加成功。

Nacos部署

前面的部署都是Seata默认的File部署,是简单的一种方式。现在就配合Nacos进行部署Seata。

添加命名空间

在Nacos中增加一个新的命名空间:seata。

修改配置文件

修改配置:seata/conf/application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#  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.

server:
port: 7091

spring:
application:
name: seata-server

logging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash

console:
user:
username: seata
password: seata

seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: file
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
application: seata-server # 如果改了这,后面在客户端配置的时候必须要用application指定服务名称
server-addr: 127.0.0.1:80
group: SEATA_GROUP
namespace: 8258f0ab-3296-45ab-8d8c-458e4ff0c700
cluster: default
username: nacos
password: nacos
store:
# support: file 、 db 、 redis
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
user: root
password: root
min-conn: 5
max-conn: 100
global-table: global_table
branch-table: branch_table
lock-table: lock_table
distributed-lock-table: distributed_lock
query-limit: 100
max-wait: 5000
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

📢修改了Seata的配置需要重启。

添加数据库

增加数据库: seata/script/server/db/mysql.sql 。创建 seatab 数据库,添加表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
-- -------------------------------- 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_status_gmt_modified` (`status` , `gmt_modified`),
KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;

-- 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 = utf8mb4;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
`row_key` VARCHAR(128) NOT NULL,
`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`),
KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;

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);

方式一

修改配置文件

修改准备导入到Nacos的文件内容(seata/script/config-center/config.txt):所有的配置只需要修改此文件即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html
#Transport configuration, for client and server
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableTmClientBatchSendRequest=false
transport.enableRmClientBatchSendRequest=true
transport.enableTcServerBatchSendResponse=false
transport.rpcRmRequestTimeout=30000
transport.rpcTmRequestTimeout=30000
transport.rpcTcRequestTimeout=30000
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

# 客户端与服务端传输方式
transport.serialization=seata
transport.compressor=none

#Transaction routing rules configuration, only for the client
service.vgroupMapping.default_tx_group=default
#If you use a registry, you can ignore it
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false

#Transaction rule configuration, only for the client
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=true
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
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
#For TCC transaction mode
tcc.fence.logTableName=tcc_fence_log
tcc.fence.cleanPeriod=1h

#Log rule configuration, for client and server
log.exceptionRate=100

#Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional.
store.mode=file
store.lock.mode=file
store.session.mode=file
#Used for password encryption
store.publicKey=

#If `store.mode,store.lock.mode,store.session.mode` are not equal to `file`, you can remove the configuration block.
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100

#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.
# 数据存储方式,db代表数据库
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=username
store.db.password=password
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

#These configurations are required if the `store mode` is `redis`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `redis`, you can remove the configuration block.

store.redis.mode=single
store.redis.single.host=127.0.0.1
store.redis.single.port=6379
store.redis.sentinel.masterName=
store.redis.sentinel.sentinelHosts=
store.redis.maxConn=10
store.redis.minConn=1
store.redis.maxTotal=100
store.redis.database=0
store.redis.password=
store.redis.queryLimit=100

#Transaction rule configuration, only for the server
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
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false

#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

修改完成后,执行:

1
script/config-center/nacos/nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 5a3c7d6c-f497-4d68-a71a-2e5e3340b3ca -u username -w password

localhost:nacos的地址

port:nacos的端口

-g:分组

-t:nacos中seata命名空间的ID

username:nacos登录名称

password:nacos登录密码

方式二

Nacos增加配置

执行seata/script/config-center/nacos/nacos-config-interactive.sh:

1
2
3
4
5
6
7
8
9
10
11
12
echo -e "Please enter the host of nacos.\n请输入nacos的host [localhost]:"
read -p ">>> " host # nacos地址
echo -e "Please enter the port of nacos.\n请输入nacos的port [8848]:"
read -p ">>> " port # 端口
echo -e "Please enter the group of nacos.\n请输入nacos的group [SEATA_GROUP]:"
read -p ">>> " group # 组,默认即可
echo -e "Please enter the tenant of nacos.\n请输入nacos的tenant:"
read -p ">>> " tenant # 命名空间ID
echo -e "Please enter the username of nacos.\n请输入nacos的username:"
read -p ">>> " username # 登录账号
echo -e "Please enter the password of nacos.\n请输入nacos的password:"
read -p ">>> " password # 登录密码

成功导入后在Nacos对应的命名空间下就可以看见导入的数据了。最后可能会显示:init nacos config fail. 可以不用管。

增加服务端模块配置

  • 新增映射配置:service.vgroupMapping.core-service-seata-service-group,其中core-service-seata-service-group是file模式中的vgroup-mapping配置。
  • 修改分组为:SEATA_GROUP
  • 配置内容为:default

📢注意:这个配置项,有多少个服务模块就需要增加几个对应的配置。

修改客户端配置

就是模块配置。修改之前的配置,之前的配置为:

1
2
3
4
5
6
7
8
9
10
seata:
service:
vgroup-mapping:
# 对事务组进行映射,默认的分组为:应用名称-seata-service-group,将其映射到default集群
core-service-seata-service-group: default
grouplist:
# seata 服务地址
default: localhost:8868
# 指定该事务组名称
# tx-service-group:

修改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
seata:
config:
type: nacos
nacos:
namespace: 8258f0ab-3296-45ab-8d8c-458e4ff0c700
username: nacos
password: nacos
server-addr: localhost:8868
registry:
type: nacos
nacos:
namespace: 8258f0ab-3296-45ab-8d8c-458e4ff0c700
server-addr: localhost:8868
username: nacos
password: nacos
# 服务名称默认seata-serve,前面如果修改了 这里也需要修改
# application: seata-serve

本文作者: 墨水记忆
本文链接: https://tothefor.com/DragonOne/65cf7865.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!