SpringCloud Alibaba系列——16Seata原理及应用(下)
作者 | 一起撸Java
来源 |今日头条
第3章 Seata
Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。在 Seata 开源之前,Seata 对应的内部版本在阿里经济体内部一直扮演着分布式一致性中间件的角色,帮助经济体平稳的度过历年的双11,对各BU业务进行了有力的支撑。经过多年沉淀与积累,商业化产品先后在阿里云、金融云进行售卖。2019.1 为了打造更加完善的技术生态和普惠技术成果,Seata 正式宣布对外开源,未来 Seata 将以社区共建的形式帮助其技术更加可靠与完备。
3.1 组成模块
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
1、Transaction Manager(TM)
- 事务管理器 - 第一个开始执行的业务系统
- 全局事务的发起员,能够根据全局事务的成功与否来对全局提交或回滚进行决策
2、Transaction Coordinator(TC) - 事务协调器 - 第三方视角,Seata-server端
- 维护全局事务的运行状态,负责协调并驱动全局事务的提交或者回滚
3、Resource Manager(RM) - 资源管理器 - 执行后面业务流程的业务系统
- 负责对分支事务进行控制,包括分支注册、状态汇报,接收协调器发来的指令,以及对本地事务的开启、提交或回滚
3.2 事务模式
1、全局事务的定义
若干分支事务的整体协调
- TM向TC申请开启一个全局事务,TC创建后,返回全局唯一XID,XID会在全局上下文中传播。
- RM向TC注册分支事务,该分支事务归属于拥有相同XID的全局事务。
- TM向TC发起全局提交或回滚
- TC调度XID的分支事务完成提交或者回滚。
理解:一个全局事务只有一个TM,但是每一个需要调用别的服务的服务也就是全局事务的发起者都应该持有或者说是具备成为一个TM的能力。
从这里我们可以看到,全局事务的发起者通过rpc调用开启远程的分支事务,并且将全局事务id通过调用链传播下去,很明显,这一条调用链只有起点能够对整条调用链的成功与否进行感知,rpc调用链让起点天然具备了决定全局提交或是回滚的能力。
2、全局事务处理过程:
- 执行阶段:执行分支事务,并保证执行结果满足是课回滚的和持久化的。
- 完成阶段:根据执行阶段结果形成的决议,应用通过TM发出的全局提交或回滚的请求给TC,TC命令RM驱动分支事务进行Commit或Rollback
3、事务模式的定义
指的是运行在Seata全局事务框架下的分支事务的行为模式,准确的说应该叫分支事务模式。
不同的事务模式区别在于分支事务使用不同的方式达到全局事务两个阶段的目标,即,回答以下两个问题
- 执行阶段:如何执行并保证执行结果满足是可回滚的和持久化的
- 完成阶段:收到TC的命令后,如何做到分支的提交或回滚
4、事务模式能力边界 - 数据库一定要支持本地事务——几乎是所有事务模式的基础
- 数据表一定要定义主键——考虑到事务的隔离性,AT里面很有用。
3.3 AT模式
回答事务模式定义的两个问题:
执行阶段:
可回滚:根据SQL解析结果,记录回滚日志
持久化:回滚日志和业务SQL在同一个本地事务中提交到数据库
完成阶段:
分支提交:异步删除回滚日志记录
分支回滚:依据回滚日志进行反向补偿更新
Seata AT模式实际上是2PC协议的一种演变方式,也是通过两个阶段的提交或者回滚来保证 多节点事务的一致性。
1、第一个阶段, 应用系统会把一个业务数据的事务操作和回滚日志记录在同一个本地事务中提交,在提交之前,会向TC(seata server)注册事务分支,并申请针对本次事务操作的表的全局锁。接着提交本地事务,本地事务会提交业务数据的事务操作以及UNDO LOG,放在一个事务中提交。
- 拦截sql并解析
- 解析sql语义
- 提取原数据 并将查询结果记录为前镜像
- 执行sql
- 保存后镜像
- 记录undolog(类似于mysql的undolog,这是事务回滚的依据),其实undolog存在的形式是由前镜像与后镜像组成的json 2、第二个阶段,这一个阶段会根据参与到同一个XID下所有事务分支在第一个阶段的执行结果来决定事务的提交或者回滚,这个回滚或者提交是TC来决定的,它会告诉当前XID下的所有事务分支,提交或者回滚。
- 如果是提交, 则把提交请求放入到一个异步任务队列,并且马上返回提交成功给到TC,这样可以避免阻塞问题。而这个异步任务,只需要删除UNDO LOG就行,因为原本的事务已经提交了。
- 如果是回滚,则开启一个本地事务,执行以下操作
(1)通过XID和Branch ID查找到响应的UNDO LOG记录
(2)数据校验,拿到UNDO LOG中after image(修改之后的数据)和当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改,这种情况需要根据配置策略来做处理。
(3)根据UNDO LOG中的before image和业务SQL的相关信息生成并执行回滚语句提交本地事务,并把本地事务的执行结果上报给TC3.3.1 事务隔离级别
那这种事务的隔离级别是什么样的呢?我们在学习数据库的事务特性时,必须会涉及到的就是事务的隔离级别,不同的隔离级别,会产生一些并发性的问题,比如
- 脏读
- 不可重复读
- 幻读
我们知道mysql的数据库隔离级别有4种,具体哪四种我们就不在这里说明。
1、写隔离
所谓的写隔离,就是多个事务对同一个表的同一条数据做修改的时候,需要保证对于这个数据更新操作的隔离性,在传统事务模型中,我们一般是采用锁的方式来实现。
那么在分布式事务中,如果存在多个全局事务对于同一个数据进行修改,为了保证写操作的隔离,也需要通过一种方式来实现隔离性,自然也是用到锁的方法,具体来说。
- 在第一阶段本地事务提交之前,需要确保先拿到全局锁,如果拿不到全局锁,则不能提交本地事务
- 拿到全局锁的尝试会被限制在一定范围内,超出范围会被放弃并回滚本地事务并释放本地锁。
举一个具体的例子,假设有两个全局事务tx1和tx2,分别对a表的m字段进行数据更新操作,m的初始值是1000。 - tx1先开始执行,按照AT模式的流程,先开启本地事务,然后更新m=1000-100=900。在本地事务更新之前,需要拿到这个记录的全局锁。
- 如果tx1拿到了全局锁,则提交本地事务并释放本地锁。
- 接着tx2后开始执行,同样先开启本地事务拿到本地锁,并执行m=900-100的更新操作。在本地事务提交之前,先尝试去获取这个记录的全局锁。而此时tx1全局事务还没提交之前,全局锁的持有者是tx1,所以tx2拿不到全局锁,需要等待
接着, tx1在第二阶段完成事务提交或者回滚,并释放全局锁。此时tx2就可以拿到全局锁来提交本地事务。当然这里需要注意的是,如果tx1的第二阶段是全局回滚,则tx1需要重新获取这个数据的本地锁,然后进行反向补偿更新实现事务分支的回滚。
此时,如果tx2仍然在等待这个数据的全局锁并且同时持有本地锁,那么tx1的分支事务回滚会失败,分支的回滚会一直重试直到tx2的全局锁等待超时,放弃全局锁并回滚本地事务并释放本地锁之后,tx1的分支事务才能最终回滚成功.
由于在整个过程中, 全局锁在tx1结束之前一直被tx1持有,所以并不会发生脏写问题。
2、读隔离
在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted) 。其实从前面的流程中就可以很显而易见的分析出来,因为本地事务提交之后,这个数据就对外可见,并不用等到tc触发全局事务的提交。
如果在特定场景下,必须要求全局的读已提交,目前Seata的方式只能通过SELECT FOR UPDATE语句来实现。
SELECT FOR UPDATE 语句的执行会申请 全局锁 ,如果 全局锁 被其他事务持有,则释放本地锁(回滚SELECT FOR UPDATE 语句的本地执行)并重试。这个过程中,查询是被 block 住的,直到 全局锁 拿到,即读取的相关数据是 已提交 的,才返回。
出于总体性能上的考虑,Seata 目前的方案并没有对所有 SELECT 语句都进行代理,仅针对 FORUPDATE 的 SELECT 语句。3.4 TCC模式
回答事务模式定义的两个问题:
执行阶段:
调用业务定义的Try方法(完全由业务层面保证可回滚和持久化)
完成阶段:
分支提交:调用各事务分支定义的Confirm方法
分支回滚:调用各事务分支定义的Cancel方法
TCC模式在上面已经讲过了,就不重复讲了,实现原理是一样的。
- 一阶段 prepare 行为
- 二阶段 commit 或 rollback 行为
根据两阶段行为模式的不同,我们将分支事务划分为 Automatic (Branch) Transaction Mode 和TCC (Branch) Transaction Mode.
AT 模式基于 支持本地 ACID 事务 的 关系型数据库:
- 一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
- 二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
- 二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。
相应的,TCC 模式,不依赖于底层数据资源的事务支持: - 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
- 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
- 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。
所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中
3.5 Saga模式
Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。这个其实就是一个最终一致性的实现。3.5.1 恢复策略
下面以下单流程为例,整个操作包括:创建订单、扣减库存、支付、增加积分。
Saga 的执行顺序有两种,如上图:
- 事务正常执行完成:T1, T2, T3, ..., Tn,例如:扣减库存(T1),创建订单(T2),支付(T3),依次有序完成整个事务。
- 事务回滚:T1, T2, ..., Tj, Cj,..., C2, C1,其中 0 < j < n,例如:扣减库存(T1),创建订单(T2),支付(T3,支付失败),支付回滚(C3),订单回滚(C2),恢复库存(C1)。
Saga定义了两种恢复策略
1、向前恢复
所谓向前恢复,就是指一些必须要成功的场景,如果某个子事务出现异常,不能回滚,而是不断触发重试来确保事务的成功。2、向后恢复
所谓向后恢复,就是指事务的回滚。也就是要往后逐项会撤销之前所有成功的子事务。3.5.2 Saga的特点
1、适用场景
- 业务流程长、业务流程多
- 参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口
2、优势 - 一阶段提交本地事务,无锁,高性能
- 事件驱动架构,参与者可异步执行,高吞吐
- 补偿服务易于实现
3、缺点 - 不保证隔离性
3.6 XA模式
回答事务模式定义的两个问题:
执行阶段:
可回滚:业务SQL操作放在XA分支中进行,由资源对XA协议的支持来保证可回滚
持久化:XA分支完成后,执行XA prepare,同样,由资源对XA协议的支持来保证持久化(即,之后任何意外都不会造成无法回滚的情况)
完成阶段:
分支提交:执行XA分支的commit
分支回滚:执行XA分支的rollback
实际上前面的三种事务方式,AT、TCC、Saga都是属于补偿性事务,补偿性事务有一个特点就是无法做到真正的全局一致性,也就是无法保证从事务框架之外的全局视角的数据一致性,所以Seata引入了XA模式的支持。
补偿型事务处理机制构建在事务资源之上(要么在中间件层面,要么在应用层面),事务资源本身对分布式事务是无感知的。(说白了就是有一个上帝视角的人在控制你的事务,你自己本身是没有感觉的,因为你只看到了你自己的本地事务,但是对于全局事务压根跟你没关系,你也感知不到)
XA模式,上一节课也讲过,它是X/Open组织定义的分布式事务处理标准(DTP,Distributed Transaction Processing)
XA 规范描述了全局的事务管理器与局部的资源管理器之间的接口。XA规范的目的是允许的多个资源(如数据库,应用服务器,消息队列等)在同一事务中访问,这样可以使 ACID 属性跨越应用程序而保持有效。
XA和补偿性不一样的点在于,XA协议要求事务资源(RM)本身提供对于XA协议的实现,这样可以使得事务资源(RM)感知并参与分布式事务的处理过程,所以事务资源(RM)可以保障从任意视角对数据的访问有效隔离并满足全局数据一致性。(说白了就是XA模式的时候,RM也参与到了全局事务的控制中了,不再是被动的被别人控制,而是自己也参与了控制)
我们先来看一下它的整体运行机制.
3.6.1 整体运行机制
XA模式实际上就是一个2pc提交,所以它的事务分为两个阶段,然后我们先看一下图中所列出来的角色,TM、RM、AP,它的关系如下图所示。XA的分布式事务是由一个或者多个RM,一个事务管理器TM以及一个应用程序AP组成。
TM: 主要负责协调参与全局事务中的各个事务,它会分配一个事务唯一标识,并监控事务的执行进度,并负责事务的执行、回滚等
AP: 应用程序,定义事务的边界(事务开始和结束),并访问事务边界内的资源
RM: 资源管理器,常见的就是数据库.在Seata的XA事务模型中,原理是一样,只是把TM的角色绑定到了TC(AT模式是任何第一个发起事务请求的RM就是TM,可以理解成TM跟RM进行绑定了),从而实现XA的事务模型,具体的实现逻辑是。1、执行阶段
- 先向TC(Seata server)注册全局事务,注册之后会分配一个xid,XA start的时候需要xid参数,这个参数可以和Seata全局事务的XID和BranchId关联,以便由TC来驱动XA分支的提交和回滚
- 向TC注册事务分支,目前Seata的BranchId是在分支注册的过程中由TC统一生成的,所以XA模式分支注册的时机需要在XA start之前。
- 通过XA Start开启XID事务,{XA START xid}
- 执行事务SQL,预提交xid事务,也就是先执行事务操作,但是这个事务并没有提交,只是像本地事务一样写入事务日志。再调用XA END xid结束xid事务
- XA Prepare XID 表示准备就绪,等待提交。然后向TC上报事务分支的执行结果
2、完成阶段 - TC根据第一阶段所有事务分支的执行结果来决定事务的提交或者回滚,XA commit / XA rollback
执行阶段
可回滚:业务 SQL 操作放在 XA 分支中进行,由资源对 XA 协议的支持来保证 可回滚
XA 分支完成后,执行 XA prepare,同样,由资源对 XA 协议的支持来保证 持久化(即,之后任何意外都不会造成无法回滚的情况)
3.6.2 XA的价值
XA和补偿性事务不同,XA协议要求事务资源本身提供对XA协议规范和协议的支持。
因为 事务资源 感知并参与分布式事务处理过程,所以 事务资源(如数据库)可以保障从任意视角对数据的访问有效隔离,满足全局数据一致性。
而这些数据的隔离性,就会依赖于数据库本身的隔离级别,如果是在读已提交之上,则不会出现脏读的情况。
除了 全局一致性 这个根本性的价值外,支持 XA 还有如下几个方面的好处:
- 业务无侵入:和 AT 一样,XA 模式将是业务无侵入的,不给应用设计和开发带来额外负担。
- 数据库的支持广泛:XA 协议被主流关系型数据库广泛支持,不需要额外的适配即可使用。
- 多语言支持容易:因为不涉及 SQL 解析,XA 模式对 Seata 的 RM 的要求比较少,为不同语言开发SDK 较之 AT 模式将更 薄,更容易。
- 传统基于 XA 应用的迁移:传统的,基于 XA 协议的应用,迁移到 Seata 平台,使用 XA 模式将更平滑。
简单的理解XA和AT模式的区别:就是AT模式在执行阶段就已经提交了,XA模式在执行阶段没有提交
3.7 Seata事务的使用
接下来,我们通过集成seata来实现一个分布式事务的使用场景。
3.7.1 Centos7安装
3.7.1.1 seata server安装
下载地址:
https://github.com/seata/seata/releases
上传到服务器/usr/local/eclipse2019
解压: tar -zxvf seata-server-1.0.0.tar.gz
进入
/usr/local/eclipse2019/seata/conf目录进行配置见4.3.7.1.1.2
在对应数据库中创建seata数据库,并创建global_table,branch_table和lock_table三张表,ddl语句如下
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 dataCREATE 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 dataCREATE 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), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_branch_id` (`branch_id`)) ENGINE = InnoDB DEFAULT CHARSET = utf8; 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);
启动服务
控制台启动[root@jt2 bin]# sh seata-server.sh -p 8091 -h 192.168.8.74 -m db 后台启动[root@jt2 bin]# nohup sh seata-server.sh -p 8091 -h 192.168.8.74 -m db > /usr/local/eclipse2019/seata/log.log 2>&1 &&:让命令在后台执行,终端退出后命令仍旧执行。2>&1 解释:将标准错误 2 重定向到标准输出 &1 ,标准输出 &1 再被重定向输入到 log.log 文件中。0 – stdin (standard input,标准输入)1 – stdout (standard output,标准输出)2 – stderr (standard error,标准错误输出)
3.7.1.1.1 存储模式
事务日志的存储方式可以支持file、 db、 redis,默认情况下采用的是file,file存储是单机模式,全局事务会话信息会持久化到${SEATA_HOME}\bin\sessionStore\root.data中。
db和redis可以支持HA,file不行,但是性能比较好。
3.7.1.1.2 服务端配置说明
Seata-Server包含两个核心配置文件,其中registry.conf表示配置Seata服务注册的地址,它目前支持所有主流的注册中心。默认是file,表示不依赖于注册中心以及配置中心。
registry.conf
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { application = "seata-server" serverAddr = "localhost:8848" group = "SEATA_GROUP" namespace = "" cluster = "default" username = "nacos" password = "nacos" }} config { # file、nacos 、apollo、zk、consul、etcd3 type = "file" file { name = "file.conf" }}
file.conf
file.conf存储的是Seata服务端的配置信息,完整的配置包含transport、Server、Metrics,分别表示协议配置,服务端配置,监控等。
service { #transaction service group mapping vgroupMapping.my_test_tx_group = "default" #only support when registry.type=file, please don't set multiple addresses default.grouplist = "127.0.0.1:8091" #disable seata disableGlobalTransaction = false} ## transaction log store, only used in seata-serverstore { ## store mode: file、db 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) etc. datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" url = "jdbc:mysql://192.168.8.137:3306/seata?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai" user = "root" password = "123456" minConn = 5 maxConn = 30 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 }}
3.7.1.2 nacos安装
下载地址:
https://github.com/alibaba/nacos/releases?page=3
上传到服务器/usr/local/eclipse2019
解压:tar -zxvf nacos-server-1.1.0.tar.gz
进入
/usr/local/eclipse2019/nacos/bin目录下执行./startup.sh -m standalone或sh startup.sh -m standalone 命令启动单机模式nacos
关闭firewall:systemctl stop firewalld.service
禁止firewall开机启动:systemctl disable firewalld.service
nacos设置开机自启动
1.添加nacos.service文件vim /lib/systemd/system/nacos.service [Unit]Description=nacosAfter=network.target [Service]Type=forkingExecStart=/usr/local/eclipse2019/nacos/bin/startup.sh -m standaloneExecReload=/usr/local/eclipse2019/nacos/bin/shutdown.shExecStop=/usr/local/eclipse2019/nacos/bin/shutdown.shPrivateTmp=true [Install] WantedBy=multi-user.target 2.加入nacos服务 systemctl daemon-reload3.设置开机自启 systemctl enable nacos.service4.启动nacos服务和关闭服务 systemctl start nacos.service systemctl stop nacos.service
3.7.2 docker安装
3.7.2.1 seata server安装
1、运行镜像
docker run --name seata-server -p 8091:8091 -d seataio/seata-server:1.0.0
2、复制配置文件到主机
docker cp seata-server:/seata-server /home/dockerdata/seata
3、停止服务
docker stop seata-server
4、删除服务
docker rm seata-server
5、设置开启自启和关键配置挂载到本地目录
docker run -d --restart always --name seata-server -p 8091:8091 -v /home/dockerdata/seata/seata-server:/seata-server -v /etc/localtime:/etc/localtime:ro -e SEATA_IP=192.168.50.128 -e SEATA_PORT=8091 --network=host seataio/seata-server:1.0.0
6、切换到配置目录
cd /home/dockerdata/seata/seata-server/resources
7、修改registry.conf文件,修为nacos启用方式,绿色字体为修改的关键地方
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { application = "seata-server" serverAddr = "192.168.8.137:8848" group = "SEATA_GROUP" namespace = "" cluster = "default" username = "nacos" password = "nacos" } 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 = "192.168.93.129:8848" namespace = "89f54c6f-3b21-46a4-bd1b-242ae159c12e" group = "DEFAULT_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" }}
项目中的库需要执行,sql文件路径:seata/script/client at develop · seata/seata · GitHub
seata服务 需要sql seata/script/server at develop · seata/seata · GitHub
不用的模式执行不同的脚本
具体的注意点查看
/home/dockerdata/seata/resources/README-zh.md
8、修改存储方式为mysql
store { ## store mode: file、db 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) etc. datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai" user = "root" password = "root" minConn = 5 maxConn = 30 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 }}
9、重启服务
docker restart seata-serverdocker logs seata-server #查看启动日志
10、可以登录nacos查看服务列表,就会发现seata-server已经注册上来了
3.7.2.2 nacos安装
docker run -d -p 8848:8848 -e MODE=standalone --network=host -v /home/dockerdata/nacos/logs:/home/nacos/logs --restart always --name nacos nacos/nacos-server:1.1.0
开放8848端口
firewall-cmd --zone=public --add-port=80/tcp --permanentfirewall-cmd --reload #重启firewall
3.7.3 AT模式使用
代码见:
https://github.com/seata/seata-samples/tree/master/springboot-dubbo-seata详细使用文档以及数据库文件见该地址下的README.md和sql
下面事该代码的业务调用逻辑图3.8 Seata集群部署
官网地址:
https://seata.io/zh-cn/docs/ops/deploy-ha.htmlSeata的数据一般会持久化到MySQL,所以不存在数据一致性的问题,所以部署集群就比较简单