zookeeper集成seata
2022-01-02 10:27:13

因为不喜欢nacos,太大很臃肿很多功能没必要,所以使用注册中心和配置中心均为zookeeper,然后基于zookeeper搭建了一个后端微服务脚手架。犯蠢忘了不同服务用的是不同数据库,但是自己测试的时候偷懒只用了一个数据库,导致分布式事务始终不生效,后来拆分数据库,测试正常。zookeeper推荐使用ZK UI导入配置文件。另在Seata 1.4.2版本中数据库中时间字段不能使用datetime类型否则会引起序列化错误。

1. 引入依赖

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
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-zookeeper-config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-config</artifactId>
<version>3.1.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-zookeeper-discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<version>3.1.0</version>
</dependency>

<!-- seata连接zk 默认连接器,不剔除就狂报错 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- seata -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>

2. 编写consumer和provider的yml

消费者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
spring:
application:
name: consumer
profiles:
active: dev # 不指定这个参数在使用zookeeper作为配置中心会报错
cloud:
zookeeper:
enabled: true # true:开启zookeeper外部化配置, false:读取本地配置; 需要将config.watcher.enabled同时设置
connect-string: 127.0.0.1:2181
discovery:
register: true
enabled: true
root: /cloud-service
config:
enabled: true
root: /cloud-config
watcher:
enabled: true
提供者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
spring:
application:
name: provider
profiles:
active: dev
cloud:
zookeeper:
enabled: true # true:开启zookeeper外部化配置, false:读取本地配置; 需要将config.watcher.enabled同时设置
connect-string: 127.0.0.1:2181
discovery:
register: true
enabled: true
root: /cloud-service
config:
enabled: true
root: /cloud-config
watcher:
enabled: true

3. 服务消费者和提供者启动类

启动类上面都新增@EnableDiscoveryClient注解

4. 将seata配置文件导入zookeeper配置中心

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
/seata=client.log.exceptionRate=100
/seata=client.report.retry.count=5
/seata=client.rm.asyncCommitBufferLimit=10000
/seata=client.rm.lockRetryInternal=10
/seata=client.rm.lockRetryPolicyBranchRollbackOnConflict=true
/seata=client.rm.lockRetryTimes=30
/seata=client.rm.reportRetryCount=5
/seata=client.rm.reportSuccessEnable=false
/seata=client.rm.sqlParserType=druid
/seata=client.rm.tableMetaCheckEnable=false
/seata=client.tm.commitRetryCount=5
/seata=client.tm.rollbackRetryCount=5
/seata=client.undo.dataValidation=true
/seata=client.undo.logSerialization=jackson
/seata=client.undo.logTable=undo_log
/seata=metrics.enabled=false
/seata=metrics.exporterList=prometheus
/seata=metrics.exporterPrometheusPort=9898
/seata=metrics.registryType=compact
/seata=server.maxCommitRetryTimeout=-1
/seata=server.maxRollbackRetryTimeout=-1
/seata=server.recovery.asynCommittingRetryPeriod=1000
/seata=server.recovery.committingRetryPeriod=1000
/seata=server.recovery.rollbackingRetryPeriod=1000
/seata=server.recovery.timeoutRetryPeriod=1000
/seata=server.rollbackRetryTimeoutUnlockEnable=false
/seata=server.undo.logDeletePeriod=86400000
/seata=server.undo.logSaveDays=7
/seata=service.default.grouplist=127.0.0.1:8091
/seata=service.disableGlobalTransaction=false
/seata=service.enableDegrade=false
/seata=service.vgroupMapping.provider-service-group=default
/seata=service.vgroupMapping.consumer-service-group=default
/seata=store.db.branchTable=branch_table
/seata=store.db.datasource=dbcp
/seata=store.db.dbType=mysql
/seata=store.db.driverClassName=com.mysql.cj.jdbc.Driver
/seata=store.db.globalTable=global_table
/seata=store.db.lockTable=lock_table
/seata=store.db.maxConn=3
/seata=store.db.minConn=1
/seata=store.db.password=123456
/seata=store.db.queryLimit=100
/seata=store.db.url=jdbc:mysql://127.0.0.1:3306/cloud?useUnicode=true
/seata=store.db.user=root
/seata=store.file.dir=file_store/data
/seata=store.file.fileWriteBufferCacheSize=16384
/seata=store.file.flushDiskMode=async
/seata=store.file.maxBranchSessionSize=16384
/seata=store.file.maxGlobalSessionSize=512
/seata=store.file.sessionReloadReadSize=100
/seata=store.mode=db
/seata=transport.compressor=none
/seata=transport.enableClientBatchSendRequest=false
/seata=transport.heartbeat=true
/seata=transport.serialization=seata
/seata=transport.server=NIO
/seata=transport.shutdown.wait=3
/seata=transport.threadFactory.bossThreadPrefix=NettyBoss
/seata=transport.threadFactory.bossThreadSize=1
/seata=transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
/seata=transport.threadFactory.clientSelectorThreadSize=1
/seata=transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
/seata=transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
/seata=transport.threadFactory.shareBossWorker=false
/seata=transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
/seata=transport.threadFactory.workerThreadSize=default
/seata=transport.type=TCP

每新加一个服务就要导入一个新的配置,xxx可以自定义

1
/seata=service.vgroupMapping.xxx=default

5. 新增seata的yml配置到provider和consumer

provider 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
seata:
enabled: true
application-id: provider-seata
tx-service-group: provider-service-group # 事务群组(可以每个应用独立取名,也可以使用相同的名字)这个群组名一定要和上面的seata=service.vgroupMapping中的xxx相等
client:
rm-report-success-enable: true
rm-table-meta-check-enable: false # 自动刷新缓存中的表结构(默认false)
rm-report-retry-count: 5 # 一阶段结果上报TC重试次数(默认5)
rm-async-commit-buffer-limit: 10000 # 异步提交缓存队列长度(默认10000)
rm:
lock:
lock-retry-internal: 10 # 校验或占用全局锁重试间隔(默认10ms)
lock-retry-times: 30 # 校验或占用全局锁重试次数(默认30)
lock-retry-policy-branch-rollback-on-conflict: true # 分支事务与其它全局回滚事务冲突时锁策略(优先释放本地锁让回滚成功)
tm-commit-retry-count: 3 # 一阶段全局提交结果上报TC重试次数(默认1次,建议大于1)
tm-rollback-retry-count: 3 # 一阶段全局回滚结果上报TC重试次数(默认1次,建议大于1)
undo:
undo-data-validation: true # 二阶段回滚镜像校验(默认true开启)
undo-log-serialization: jackson # undo序列化方式(默认jackson)
undo-log-table: undo_log # 自定义undo表名(默认undo_log)
support:
spring:
datasource-autoproxy: true
service:
vgroup-mapping:
my_test_tx_group: default # TC 集群(必须与seata-server保持一致)
enable-degrade: false # 降级开关
disable-global-transaction: false # 禁用全局事务(默认false)
grouplist:
default: 127.0.0.1:8091
transport:
shutdown:
wait: 3
thread-factory:
boss-thread-prefix: NettyBoss
worker-thread-prefix: NettyServerNIOWorker
server-executor-thread-prefix: NettyServerBizHandler
share-boss-worker: false
client-selector-thread-prefix: NettyClientSelector
client-selector-thread-size: 1
client-worker-thread-prefix: NettyClientWorkerThread
type: TCP
server: NIO
heartbeat: true
serialization: seata
compressor: none
enable-client-batch-send-request: true # 客户端事务消息请求是否批量合并发送(默认true)
registry:
file:
name: file.conf
type: zk
zk:
server-addr: 127.0.0.1:2181
config:
file:
name: file.conf
type: zk
zk:
server-addr: 127.0.0.1:2181
consumer 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
seata:
enabled: true
application-id: consumer-seata
tx-service-group: consumer-service-group # 事务群组(可以每个应用独立取名,也可以使用相同的名字)这个群组名一定要和上面的seata=service.vgroupMapping中的xxx相等
client:
rm-report-success-enable: true
rm-table-meta-check-enable: false # 自动刷新缓存中的表结构(默认false)
rm-report-retry-count: 5 # 一阶段结果上报TC重试次数(默认5)
rm-async-commit-buffer-limit: 10000 # 异步提交缓存队列长度(默认10000)
rm:
lock:
lock-retry-internal: 10 # 校验或占用全局锁重试间隔(默认10ms)
lock-retry-times: 30 # 校验或占用全局锁重试次数(默认30)
lock-retry-policy-branch-rollback-on-conflict: true # 分支事务与其它全局回滚事务冲突时锁策略(优先释放本地锁让回滚成功)
tm-commit-retry-count: 3 # 一阶段全局提交结果上报TC重试次数(默认1次,建议大于1)
tm-rollback-retry-count: 3 # 一阶段全局回滚结果上报TC重试次数(默认1次,建议大于1)
undo:
undo-data-validation: true # 二阶段回滚镜像校验(默认true开启)
undo-log-serialization: jackson # undo序列化方式(默认jackson)
undo-log-table: undo_log # 自定义undo表名(默认undo_log)
support:
spring:
datasource-autoproxy: true
service:
vgroup-mapping:
my_test_tx_group: default # TC 集群(必须与seata-server保持一致)
enable-degrade: false # 降级开关
disable-global-transaction: false # 禁用全局事务(默认false)
grouplist:
default: 127.0.0.1:8091
transport:
shutdown:
wait: 3
thread-factory:
boss-thread-prefix: NettyBoss
worker-thread-prefix: NettyServerNIOWorker
server-executor-thread-prefix: NettyServerBizHandler
share-boss-worker: false
client-selector-thread-prefix: NettyClientSelector
client-selector-thread-size: 1
client-worker-thread-prefix: NettyClientWorkerThread
type: TCP
server: NIO
heartbeat: true
serialization: seata
compressor: none
enable-client-batch-send-request: true # 客户端事务消息请求是否批量合并发送(默认true)
registry:
file:
name: file.conf
type: zk
zk:
server-addr: 127.0.0.1:2181
config:
file:
name: file.conf
type: zk
zk:
server-addr: 127.0.0.1:2181

6. 下载seata并修改配置文件

修改file.conf

按照图中标识修改配置文件中的参数

修改registry.conf

按照图中标识修改配置文件中的参数

7. 各个子服务的数据库导入seata的sql

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
/*
Navicat Premium Data Transfer

Source Server Type : MySQL
Source Server Version : 80025

Target Server Type : MySQL
Target Server Version : 80025
File Encoding : 65001

Date: 02/01/2022 10:57:18
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for branch_table
-- ----------------------------
DROP TABLE IF EXISTS `branch_table`;
CREATE TABLE `branch_table` (
`branch_id` bigint NOT NULL,
`xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`transaction_id` bigint NULL DEFAULT NULL,
`resource_group_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`lock_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`branch_type` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`status` tinyint NULL DEFAULT NULL,
`client_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`application_data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`gmt_create` datetime NULL DEFAULT NULL,
`gmt_modified` datetime NULL DEFAULT NULL,
PRIMARY KEY (`branch_id`) USING BTREE,
INDEX `idx_xid`(`xid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for global_table
-- ----------------------------
DROP TABLE IF EXISTS `global_table`;
CREATE TABLE `global_table` (
`xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`transaction_id` bigint NULL DEFAULT NULL,
`status` tinyint NOT NULL,
`application_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`transaction_service_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`transaction_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`timeout` int NULL DEFAULT NULL,
`begin_time` bigint NULL DEFAULT NULL,
`application_data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`gmt_create` datetime NULL DEFAULT NULL,
`gmt_modified` datetime NULL DEFAULT NULL,
PRIMARY KEY (`xid`) USING BTREE,
INDEX `idx_gmt_modified_status`(`gmt_modified`, `status`) USING BTREE,
INDEX `idx_transaction_id`(`transaction_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for lock_table
-- ----------------------------
DROP TABLE IF EXISTS `lock_table`;
CREATE TABLE `lock_table` (
`row_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`xid` varchar(96) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`transaction_id` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
`branch_id` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
`resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`table_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`pk` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`gmt_create` datetime NULL DEFAULT NULL,
`gmt_modified` datetime NULL DEFAULT NULL,
PRIMARY KEY (`row_key`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`branch_id` bigint NOT NULL,
`xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 30 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

执行seata-server.sh,在需要保持事务的Service加上@GlobalTransactional即可