Seata中文参考文档: http://seata.io/zh-cn/docs/overview/what-is-seata.html
一、什么是微服务架构
“微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务和服务之间采用轻量级的通信机制相互沟通(通常是基于HTTP的Restful API).每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建"
二、分布式事务的产生
1. 单体架构
一个用户完整的下单过程,在单体应用中,只需要一个在一个项目中,一个数据库里,通过调用下下单接口,下单时调用扣减库存方法和扣减账户余额来完成一笔订单。
2. 分布式架构
单体应用被拆分成微服务应用,原来的三个模块被拆分成三个独立的应用,分别使用不同的数据源,在业务操作上需要调用三个服务来完成。此时每个服务内部的数据一致性由本地事务来保证,但是全局的数据一致性问题没法保证,分布式事务由此产生。
三、Seata概念入门
1. Seata是什么
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,默认使用AT模式,为用户打造一站式的分布式解决方案。
2. AT 模式
前提
- 基于支持本地 ACID 事务的关系型数据库。
- Java 应用,通过 JDBC 访问数据库。
整体机制
通过2PC两阶段提交协议的演变:
- 一阶段: 业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
- 二阶段: 提交异步化,成功则批量地删除相应回滚日志记录,失败则通过回滚日志进行反向补偿。
写隔离
- 1)、 一阶段本地事务提交前,需要确保先拿到全局锁。
- 2)、拿不到全局锁,不能提交本地事务;拿到全局锁,提交本地事务并插入undo_log记录。
- 3)、拿全局锁的尝试被限制在一定范围内,超出范围将放弃,并根据undo_log记录回滚本地事务,释放本地锁。
读隔离
- 1)、在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted)。
理解: 在全局事务提交之前,本地事务会先提交,这时候查询数据,对于本地库是Read Committed,对于全局来说是 Read Uncommitted。 - 2)、如果要求全局的读已提交,目前 Seata 的方式是通过 SELECT FOR UPDATE 语句的代理。
3. TCC模式
TCC不依赖 RM 对分布式事务的支持,而是通过对业务逻辑的分解来实现分布式事务。
- 1)、初步操作 Try: 完成所有业务检查,预留必须的业务资源。
- 2)、确认操作 Confirm: 真正执行的业务逻辑,不做任何业务检查,只使用 Try 阶段预留的业务资源。因此,只要 Try 操作成功,Confirm 必须能成功。另外,Confirm 操作需满足幂等性,保证一笔分布式事务能且只能成功一次。
- 3)、取消操作 Cancel: 释放 Try 阶段预留的业务资源。同样的,Cancel 操作也需要满足幂等性。
所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。
4. SAGA模式
概述
Seata
提供的长事务解决方案,在Saga
模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
适用场景:
- 业务流程长、业务流程多
- 参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口
优势:
- 一阶段提交本地事务,无锁,高性能
- 事件驱动架构,参与者可异步执行,高吞吐
- 补偿服务易于实现
缺点:
不保证隔离性
基于状态机引擎的 Saga 实现。
目前SEATA提供的Saga模式是基于状态机引擎来实现的,机制是:
- 通过状态图来定义服务调用的流程并生成 json 状态语言定义文件。
- 状态图中一个节点可以是调用一个服务,节点可以配置它的补偿节点。
- 状态图 json 由状态机引擎驱动执行,当出现异常时状态引擎反向执行已成功节点对应的补偿节点将事务回滚,异常发生时是否进行补偿也可由用户自定义决定。
- 可以实现服务编排需求,支持单项选择、并发、子流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能。
示例状态图:
5. XA 模式
前提
- 支持XA 事务的数据库。
- Java 应用,通过 JDBC 访问数据库。
整体机制
在 Seata 定义的分布式事务框架内,利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种 事务模式。
- 执行阶段:
- 可回滚:业务 SQL 操作放在 XA 分支中进行,由资源对 XA 协议的支持来保证 可回滚
- 持久化:XA 分支完成后,执行 XA prepare,同样,由资源对 XA 协议的支持来保证 持久化(即,之后任何意外都不会造成无法回滚的情况)
- 完成阶段:
- 分支提交:执行 XA 分支的 commit
- 分支回滚:执行 XA 分支的 rollback
关于XA模式的介绍这里先简单提一下,更详细的信息查阅 :http://seata.io/zh-cn/docs/dev/mode/xa-mode.html
四、Seata模型介绍
Seata的整个过程模型如下图所示:
上图中主要有三种角色:
- TM:事务管理者,用来告诉 TC,全局事务的开始,提交,回滚。
- TC:事务协调者,即seata-server,维护全局事务和分支事务的状态,通知各RM提交或者回滚。
- RM:资源管理者,每一个 RM 都会作为一个分支事务注册在 TC,负责分支事务的注册、提交和回滚。
术语介绍:
- XID - Transaction ID ,一个分布式事务唯一一个ID。
- TC - 事务协调者,维护全局和分支事务的状态,驱动全局事务提交或回滚。
- TM - 事务管理器,定义全局事务的范围:开始全局事务、提交或回滚全局事务。
- RM - 资源管理器,管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
典型的分布式事务处理流程包括以下步骤:
- TM向TC请求开启一个全局事务,TC给TM返回一个全局事务的XID,即XID;
- XID在微服务调用链路的上下文间传播;
- RM向TC注册分支事务,将其纳入XID对应全局事务的管辖;
- TM根据XID向TC发出提交或者回滚的请求;
- TC根据XID使RM提交或者回滚
流程图如下:
五、关于Seata架构
早在2019年,阿里开源了分布式事务框架Seata,原名叫Fescar,后来跟蚂蚁TCC方案整合后改名为Seata,截止目前2020年11月3日,Seata已经更新到v1.4.0版本了,虽然在之前的版本发布中,存在一些潜在的问题,但是通过开源团队快速修复问题,并且快速迭代发布新版本之下,目前相对较稳定。
同时相比与其它分布式事务框架,Seata架构的亮点主要有几个:
- 应用层基于SQL解析实现了自动补偿,从而最大程度的降低业务侵入性;
- 将分布式事务中TC(事务协调者)独立部署,负责事务的注册、回滚;
- 通过全局锁实现了写隔离与读隔离。
六、参考文档
Seata中文官方文档: http://seata.io/zh-cn/docs/overview/what-is-seata.html
Seata-Server下载地址: https://github.com/seata/seata/releases
分布式事务Demo: https://github.com/seata/seata-samples
Seata源码地址: https://github.com/seata/seata