分布式事务解决方案seata架构的安装摆设(AT模式)
1.介绍seata官网:Seata 是什么? | Apache Seata
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简朴易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案
在Seata的事务管理中有三个紧张的脚色:
[*] TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
[*] TM (Transaction Manager) - 事务管理器:界说全局事务的范围、开始全局事务、提交或回滚全局事务。
[*] RM (Resource Manager) - 资源管理器:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
https://i-blog.csdnimg.cn/direct/6d95b21e99144b03935e443679c0b850.png
其中,TM和RM可以理解为Seata的客户端部分,引入到参与事务的微服务依赖中即可。将来TM和RM就会帮忙微服务,实现本地分支事务与TC之间交互,实现事务的提交或回滚。而TC服务则是事务协调中心,是一个独立的微服务,需要单独摆设。
https://i-blog.csdnimg.cn/direct/d80b7adf24b2422ca1d2e7d70dad1cd7.png
https://i-blog.csdnimg.cn/direct/ba119b8fe13a4453867981ed91b83959.png
2.摆设TC服务
2.1 导入数据库表
Seata支持多种存储模式,但考虑到持久化的需要,我们一般选择基于数据库存储。因此需要创建一个数据库‘seata’,运行一下sql命令。
CREATE DATABASE IF NOT EXISTS `seata`;
USE `seata`;
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;
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;
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_and_branch_id` (`xid` , `branch_id`)
) 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); 2.2.准备配置文件
创建一个seata文件夹,在该文件夹下创建一个application.yml文件,写入配置信息,例:
server:
port: 7099
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
seata:
config:
# support: nacos 、 consul 、 apollo 、 zk、 etcd3
type: file
nacos:
server-addr: 127.0.0.1:8848
namespace:
group: SEATA_GROUP
username:
password:
data-id: seataServer.properties
consul:
server-addr: 127.0.0.1:8500
acl-token:
key: seata.properties
apollo:
appId: seata-server
apollo-meta: http://192.168.1.204:8801
apollo-config-service: http://192.168.1.204:8080
namespace: application
apollo-access-key-secret:
cluster: seata
zk:
server-addr: 127.0.0.1:2181
session-timeout: 6000
connect-timeout: 2000
username:
password:
node-path: /seata/seata.properties
etcd3:
server-addr: http://localhost:2379
key: seata.properties
registry:
# support: nacos 、 eureka 、 redis 、 zk、 consul 、 etcd3 、 sofa
type: file
preferred-networks: 30.240.*
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
cluster: default
username:
password:
eureka:
service-url: http://localhost:8761/eureka
application: default
weight: 1
redis:
server-addr: localhost:6379
db: 0
password:
cluster: default
timeout: 0
zk:
cluster: default
server-addr: 127.0.0.1:2181
session-timeout: 6000
connect-timeout: 2000
username: ""
password: ""
consul:
cluster: default
server-addr: 127.0.0.1:8500
acl-token:
etcd3:
cluster: default
server-addr: http://localhost:2379
sofa:
server-addr: 127.0.0.1:9603
application: default
region: DEFAULT_ZONE
datacenter: DefaultDataCenter
cluster: default
group: SEATA_GROUP
address-wait-time: 3000
server:
service-port: 8091 #If not configured, the default is '${server.port} + 1000'
max-commit-retry-timeout: -1
max-rollback-retry-timeout: -1
rollback-retry-timeout-unlock-enable: false
enableCheckAuth: true
retryDeadThreshold: 130000
recovery:
committing-retry-period: 1000
asyn-committing-retry-period: 1000
rollbacking-retry-period: 1000
timeout-retry-period: 1000
undo:
log-save-days: 7
log-delete-period: 86400000
store:
# support: file 、 db 、 redis
mode: file
session:
mode: file
lock:
mode: file
file:
dir: sessionStore
max-branch-session-size: 16384
max-global-session-size: 512
file-write-buffer-cache-size: 16384
session-reload-read-size: 100
flush-disk-mode: async
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true
user: mysql
password: mysql
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
redis:
mode: single
database: 0
min-conn: 1
max-conn: 10
password:
max-total: 100
query-limit: 100
single:
host: 127.0.0.1
port: 6379
sentinel:
master-name:
sentinel-hosts:
metrics:
enabled: false
registry-type: compact
exporter-list: prometheus
exporter-prometheus-port: 9898 本身更改端口号、nacos地址和数据库地址、暗码即可。将整个seata文件夹拷贝到假造机的/root目次
2.3 Docker摆设
需要注意,要确保nacos、mysql都在同一个Docker网络中。如果某个容器不在Docker网络,可以参考下面的命令将某容器加入指定网络:
docker network connect [网络名] [容器名] 可以使用以下命令检查某个容器在哪个网络,
docker inspect [容器名] 例如:我使用 docker inspect mysql ,,可以看到该容器在“elk”网络中
https://i-blog.csdnimg.cn/direct/acad6ca61b054016b54aa640506f36ad.png
在假造机的/root目次执行下面的命令:,将Docker网络和上面配置信息的ip地址改成本身对应的
docker run --name seata \
-p 8099:8099 \
-p 7099:7099 \
-e SEATA_IP=172.0.0.1 \
-v ./seata:/seata-server/resources \
--privileged=true \
--network elk \
-d \
seataio/seata-server:1.5.2 https://i-blog.csdnimg.cn/direct/7027b38c54ee46e297a6d5984b9ec5b4.png
安装完成后可以通过欣赏器访问127.0.0.1:1099 进入seata界面,初次登录账号暗码都是admin
https://i-blog.csdnimg.cn/direct/e978e662c16b46c18e6fe1c408473885.png
进入后可以看到事务的信息和一些锁的信息:
https://i-blog.csdnimg.cn/direct/4080b723e6f54ca69cc901545d519a94.png
3.微服务集成Seata
3.1 引入依赖
为了方便各个微服务集成seata,我们需要把seata配置共享到nacos,因此模块不仅仅要引入seata依赖,还要引入nacos依赖:
<!--统一配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--读取bootstrap文件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency> 3.2 改造配置
在nacos上添加一个共享的seata配置,命名为shared-seata.yaml
将nacos ip地址改成本身的
seata:
registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
type: nacos # 注册中心类型 nacos
nacos:
server-addr: 127.0.0.1:8848 # nacos地址 ,ip改成自己服务器地址
namespace: "" # namespace,默认为空
group: DEFAULT_GROUP # 分组,默认是DEFAULT_GROUP
application: seata-server # seata服务名称
username: nacos
password: nacos
tx-service-group: hmall # 事务组名称
service:
vgroup-mapping: # 事务组与tc集群的映射关系
hmall: "default" 然后,改造模块,添加bootstrap.yaml
spring:
application:
name: trade-service # 服务名称
profiles:
active: dev
cloud:
nacos:
server-addr: 172.0.0.1:8848 # nacos地址
config:
file-extension: yaml # 文件后缀名
shared-configs: # 共享配置
- dataId: shared-jdbc.yaml # 共享mybatis配置
- dataId: shared-log.yaml # 共享日志配置
- dataId: shared-swagger.yaml # 共享日志配置
- dataId: shared-seata.yaml # 共享seata配置 再改造application.yaml文件,将重复的部分删掉
3.3添加数据库
在涉及分布式事务的微服务的数据库中运行下面sql语句=>创建undo_log表格
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` DATETIME(6)NOT NULL COMMENT 'create datetime',
`log_modified`DATETIME(6)NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
3.4实现方法:
在涉及分布式事务的业务代码上加上Seata提供的@GlobalTransactional注解即可
@GlobalTransactional
在配置文件中指定要采用的分布式事务模式。我们可以在Nacos中的共享shared-seata.yaml配置文件中设置:
seata:
data-source-proxy-mode: XA
JDK17运行报错可以见:JDK17运行seata发生报错Error creating bean with name ‘globalTransactionScanner‘的解决方案-CSDN博客
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]