seata的使用

Seata 是什么

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和XA 事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS(Global Transaction Service 全局事务服务)

官 网 :https://seata.io/zh-cn/index.html 源码: https://github.com/seata/seata

官方Demo: https://github.com/seata/seata-samples seata版本:v1.4.0

Seata的三大角色

在 Seata 的架构中,一共有三个角色:

TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。其中,TC 为单独部署的 Server 服务端,TM 和 RM 为嵌入到应用中的 Client 客户端。

在 Seata 中,一个分布式事务的生命周期如下:

TM 请求 TC 开启一个全局事务。TC 会生成一个 XID 作为该全局事务的编号。XID,会在微服务的调用链路中传播,保证将多个微服务的子事务关联在一起。

当一进入事务方法中就会生成XID , global_table 就是存储的全局事务信息 , 2.RM 请求 TC 将本地事务注册为全局事务的分支事务,通过全局事务的 XID 进行关联。

当运行数据库操作方法,branch_table 存储事务参与者3.TM 请求 TC 告诉 XID 对应的全局事务是进行提交还是回滚。

4.TC 驱动 RM 们将 XID 对应的自己的本地事务进行提交还是回滚。

设 计 思 路                                                                   

AT模式的核心是对业务无侵入,是一种改进后的两阶段提交,其设计思路如图

第一阶段

业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。核心在于对业务sql进行解析,转换成undolog,并同时

入库,这是怎么做的呢?先抛出一个概念DataSourceProxy代理数据源,通过名字大家大概也能基本猜到是什么个操作,后面做具体分析参考官方文档: Seata AT 模式

第二阶段

分布式事务操作成功,则TC通知RM异步删除undolog

分布式事务操作失败,TM向TC发送回滚请求,RM 收到协调器TC发来的回滚请求,通过 XID 和 Branch ID 找到相应的回滚日志记录,通过回滚记录生成反向的更新 SQL 并执行,以完成分支的回滚。

 整体执行流程

 设计亮点

相比与其它分布式事务框架,Seata架构的亮点主要有几个:

  1. 应用层基于SQL解析实现了自动补偿,从而最大程度的降低业务侵入性;
  2. 将分布式事务中TC(事务协调者)独立部署,负责事务的注册、回滚;
  3. 通过全局锁实现了写隔离与读隔离。

存在的问题

性能损耗

一条Update的SQL,则需要全局事务xid获取(与TC通讯)、before image(解析SQL,查询一次数据库)、after image(查询一次数据库)、insert undo log(写一次数据库)、before commit(与TC通讯,判断锁冲突),这些操作都需要一次远程通讯RPC,而且是同步的。另外undo log写入时blob字段的插入性能也是不高的。每条写SQL都会增加这么多开销,粗略估计会增加5倍响应时间。

性价比

为了进行自动补偿,需要对所有交易生成前后镜像并持久化,可是在实际业务场景下,这个是成功率有多高,或者说分布式事务失败需要回滚的有多少比率?按照二八原则预估,为了20%的交易回滚,需要将80%的成功交易的响应时间增加5倍,这样的代价相比于让应用开发一个补偿交易是否是值得?

全局锁

热点数据

相比XA,Seata 虽然在一阶段成功后会释放数据库锁,但一阶段在commit前全局锁的判定也拉长了对数据锁的占有时间,这个开销比XA的prepare低多少需要根据实际业务场景进行测试。全局锁的引入实现了隔离性,但带来的问题就是阻塞,降低并发性,尤其是热点数据,这个问题会更加严重。

回滚锁释放时间

Seata在回滚时,需要先删除各节点的undo log,然后才能释放TC内存中的锁,所以如果第二阶段是回滚,释放锁的时间会更长。

死锁问题

Seata的引入全局锁会额外增加死锁的风险,但如果出现死锁,会不断进行重试,最后靠等待全局锁超时,这种方式并不优雅,也延长了对数据库锁的占有时间。

Seata快速开始

Seata Server(TC)环境搭建

 先下载包(第一个相当于是seata的工具集,tar.gz是Linux版,zip是windows版)具体版本根据组件版本关系进行下载https://github.com/seata/seata/releases

 

 首先将tar包上传到Linux上,解压

cd /opt/
tar -zxf seata-server-1.3.0.tar.gz

移动并重命名

mv seata /soft/seata130

将工具包里的script文件拖至/soft/seata130/ 文件下

修改配置文件 

cd /opt/soft/seata130/conf/

vim file.conf

#修改一下内容
将mode = "file" 改为 mode = "db"
将连接数据库 url地址改为mysql的服务器地址,数据库名可改可不该
user="root"
password="abc123" #数据库密码

 进入mysql数据库

mysql -uroot -pabc123

#创建数据库,名要和上面配置文件中的数据库名一样
create database seata_server

use seata_server;

source /opt/soft/seata130/script/server/db/mysql.sql

 

 将Seata Server注册到Nacos,修改conf目录下的registry.conf配置

cd /opt/soft/seata130/conf

vim registry.conf

#修改内容
type="nacos"

serverAddr="192.168.187.150:8849" #改为nacos服务器的地址
namespace="public"
username="nacos"
password="nacos"

配置Nacos配置中心 registry.conf,跟上面一样,group名和上面的要保持一致

注意:如果配置了seata server使用nacos作为配置中心,则配置信息会从nacos读取,file.conf可以不用配置。 客户端配置registry.conf 使用nacos时也要注意group要和seata server中的group一致,默认group是"DEFAULT_GROUP"

cd opt/soft/seata130/script/config-center/config.txt,修改配置信息

 配置事务分组, 要与客户端配置的事务分组一致

#my_test_tx_group需要与客户端保持一致 default需要跟客户端和registry.conf中registry中的cluster保持一致

(客户端properties配置:spring.cloud.alibaba.seata.tx‐service‐group=my_test_tx_group)

事务分组: 异地机房停电容错机制

my_test_tx_group 可以自定义 比如:(guangzhou、shanghai...) , 对应的client也要去设置

这里比如说,seata有两个组,一个在南京,一个在广州,my_test_tx_group可以定义去使用哪一个组,如果nanjing的seata都断电用不了了,则直接改为guangzhou组启动就可以了

 

 我这里改为nanjing

 

 启动nacos服务器

sh /opt/soft/nacos/bin/startup.sh

配置参数同步到Nacos

cd /opt/soft/seata130/script/config-center/nacos

#需要授权
chown 777 nacos-config.sh

 # sh ${SEATAPATH}/script/config‐center/nacos/nacos‐config.sh ‐p 8850 -u nacos -w nacos

./nacos-conf.sh -p 8849 -u nacos -w nacos

参数说明:可跟

-h: host,默认值 localhost

-p: port,默认值 8848,这里改为nacos的端口号

-g: 配置分组,默认值为 'SEATA_GROUP'

-u: nacos用户名

-w: nacos密码

-t: 租户信息,对应 Nacos 的命名空间ID字段, 默认值为空 ''

成功后,进入nacos中心,就会看到很多的配置文件进去了

启动Seata Server,端口号可以自己随便给

# 命令启动: bin/seata-server.sh -h 127.0.0.1 -p 8091 -m db -n 1 -e test

cd /opt/soft/seata130/bin/

./seata.server.sh -p 9001 -n 1
./seata.server.sh -p 9002 -n 2
./seata.server.sh -p 9003 -n 3

启动成功后,进入nacos可看到,上面启动三个,这里seata-server的实例数应该是3,这样就相当于是seata集群

Seata Client快速开始

1)启动Seata server端,Seata server使用nacos作为配置中心和注册中心(上一步已完成)

2)配置微服务整合seata

添加依赖(用到几个服务,就在哪个服务中都添加依赖)

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring‐cloud‐starter‐alibaba‐seata</artifactId>
</dependency>

各微服务对应数据库中添加undo_log表

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,
    PRIMARY KEY (`id`),
    UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

添加application.yml配置(涉及的微服模块都添加)

配置seata 服务事务分组,要与服务端nacos配置中心中service.vgroup_mapping的后缀对应

seata:
  tx-service-group: nanjing
  config:
    nacos:
      server-addr: 192.168.88.190:8850
      username: nacos
      password: nacos
      namespace: public
    type: nacos
  registry:
    nacos:
      server-addr: 192.168.88.190:8850
      username: nacos
      password: nacos
      namespace: public

在nacos配置中心上找到service.default.grouplist配置,改其配置参数为seata服务的端口与ip

 

 微服务发起者(TM 方)需要添加@GlobalTransactional注解

分布式事务成功,模拟正常下单、扣库存,扣余额

分布式事务失败,模拟下单扣库存成功、扣余额失败,事务是否回滚

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值