分布式事务设计⽂档
1 背景
在分布式环境下,每个应⽤使⽤不同的数据库。传统地,⼀个服务中使⽤⼀次事务,⽆法保证全局的事务特性。随着系统的发展,微服务拆分,分布式事务问题变得尤为严峻。
过去我们采⽤补数据的⽅式来应对这种紧急情况。但是在交易量增⼤、并发增多、业务复杂的情况下,仅靠⼈⼯处理难以满⾜系统发展的要求。
从长远来看,我们需要在系统间实现⼀套机制,当交易出现异常,能尽快地回滚到交易最初的数据,在出现紧急情况,我们能在系统间建⽴起⼀套良性的能满⾜定制化需求的⽅案。
2 实现⽬标
1. 建⽴起⼀套机制,通过框架来保证跨系统事务⼀致性问题。
2. 在这套机制下,提供个性化需求开发的⼊⼝。
3. 如⽀持⼿⼯重发处理、订单查询等。
4. 实现nutz和spring两套框架⽀持。
5. 只影响需要分布式事务问题的服务。 尽量减少开发⼯作量。
3 设计⽅向
3.1 事务的ACID特性
传统的关系性数据库⽀持事务,⽽事务体现在ACID四个特性上。
- Atomicity:原⼦性(要么都做,要么都不做)
- Consistency:⼀致性(数据库只有⼀个状态,不存在未确定状态)
- Isolation:隔离性(事务之间互不⼲扰)
- Durability: 永久性(事务⼀旦提交,数据库记录永久不变)
如果是单个应⽤,我们很容易通过关系型数据库来实现事务,⽽在微服务的环境下,每个应⽤都有单独的数据库,因此我们不能简单地依靠数据库来实现事务。
分布式和微服务的关系 我们需要寻在分布式环境,微服务架构中,寻事务⼀致性的⽅案。
3.2 CAP原则和BASE理论
CAP原则和BASE理论被公认是分布式系统设计的基础和⽅向理论。
3.2.1 CAP原则
CAP原则,指的是在⼀个分布式系统中,Consistency(⼀致性)、 Availability(可⽤性)、Partition tolerance(分区容错性),三者不可得兼。
- C:Consistency,⼀致性,所有数据变动都是同步的。
- A:Availability,可⽤性,即在可以接受的时间范围内正确地响应⽤户请求。
- P:Partition tolerance,分区容错性,即某节点或⽹络分区故障时,系统仍能够提供满⾜⼀致性和可⽤性的服务。
3.2.2 BASE理论
BASE 理论主要是解决 CAP 理论中分布式系统的可⽤性和⼀致性不可兼得的问题。BASE理论被认为是分布式系统理想的解决⽅案。
-
BA:Basically Available,基本可⽤。
- S:Soft State,软状态,状态可以有⼀段时间不同步。
- E:Eventually Consistent,最终⼀致,最终数据是⼀致的就可以了,⽽不是时时保持强⼀致。
3.3 思考的⽅向
BASE理论指⽰我们,如果⽆法同时实现CAP特性,可以牺牲强⼀致性,保证可⽤性。可以通过补偿来恢复最终⼀致性。
4 实现⽅案
4.1 全局事务
全局事务管理器⼀般使⽤XA⼆阶段提交(2PC)协议与数据库进⾏交互。
XA协议由Tuxedo⾸先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接⼝标准。⽬前,Oracle、Informix、DB2和Sybase等各⼤数据库⼚家都提供对XA的⽀持。XA协议采⽤两阶段提交⽅式来管理分布式事务。
RM(Resource Manager):资源管理器(这⾥可以是⼀个DBMS,或者消息服务器管理系统)应⽤程序通过资源管理器对资源进⾏控制,资源必须实现XA 定义的接⼝;
TM(Transaction Manager):事务管理器,负责协调和管理事务,提供给AP应⽤程序编程接⼝以及管理资源管理器。
实际上全局事务是把不同应⽤服务的事务绑定在⼀个事务,在数据库的层⾯实现了事务的问题。两阶段提交保证保证上下游系统都处理完⾃⼰的事情再提交事务。由此⽽引申出另外⼀个问题,可⽤性降低。全局事务会把数据锁定很长⼀段时间,上下游系统都要等待全局事务处理完才释放。
全局事务是反伸缩的设计,反微服务的设计,会严重影响系统性能。虽然最终能解决事务问题,但不适合在微服务架构系统中使⽤。⽬前使⽤也⽐较少。
4.2 冲正
冲正指的是当原交易失败的时候,发起反交易,撤销原交易的处理结果。冲正在传统银⾏中使⽤较多。
上⾯是⼀个典型的跨系统冲正交易流程图:
1. 上游系统调⽤下游系统发起t1交易。
2. 下游系统处理完成,返回成功。
3. 上游系统继续处理内部业务失败,回滚本地事务。
4. 上游系统主动调⽤冲正交易-t1,冲掉原交易。
5. 下游系统返回冲正成功,此时两边数据⼀致。
但是这⾥存在很多问题:
1. 如果冲正交易调⽤失败/超时,怎么处理?
2. 需要开发⼈员把冲正交易编写到代码⾥⾯。
3. 将冲正业务渗透到了原交易,严重影响响应时间。
4. ⽆法监控、重发。
总结来说,发起反交易是分布式事务处理的⼀种思路,但是这种实现太简单,隐患太多。
4.3 tcc 模型
tcc 被认为是业务层的2PC⽅案,它不是在资源管理层实现的两阶段提交,⽽是在业务层实现。
Try: 尝试执⾏业务
完成所有业务检查(⼀致性)
预留必须业务资源(准隔离性)
Confirm:确认执⾏业务
真正执⾏业务
不作任何业务检查
只使⽤Try阶段预留的业务资源
Confirm操作满⾜幂等性
Cancel: 取消执⾏业务
释放Try阶段预留的业务资源
Cancel操作满⾜幂等性
与2PC协议⽐较
- 位于业务服务层⽽⾮资源层
- 没有单独的准备(Prepare)阶段,Try操作兼备资源操作与准备能⼒
- Try操作可以灵活选择业务资源的锁定粒度
- 较⾼开发成本
这是⼀个典型的TCC模型图,业务活动管理器相当于2PC协议的TM,管理着服务事务的提交或者撤销。TCC模式是冲正模式的引申,它通过框架来实现,并且通过可以定时任务和消息等机制让交易实现最终⼀致性,并且通过框架尽量地实现稳定性、可扩展性。
⽬前相关的开源插件有tcc-transaction 和 byte-tcc。蚂蚁⾦服有⾃⼰的tcc插件,不过要收费。
4.4 基于可靠消息的最终⼀致性
与第三⽅系统交互或者与下游系统(被动⽅)交互,如果被动⽅需要可靠的结果调⽤,并且调⽤满⾜幂等性(多次调⽤结果⼀致),同时对⼀定时间延迟不介意,可以使⽤基于可靠消息的最终⼀致性⽅案。
可靠消息,指的是当消息主动⽅,处理完本地事务时候,可靠地给被动⽅发送消息。
4.4.1 正常场景
1. 主动⽅应⽤先把消息发给消息中间件,消息状态标记为“待确认”;
2. 消息中间件收到消息后,把消息持久化到消息存储中,但并不向被动⽅应⽤投递消息;
3. 消息中间件返回消息持久化结果(成功/失败),主动⽅应⽤根据返回结果进⾏判断如何进⾏业务操作处理: - 失败:放弃业务操作处理,结束(必要时向上层返回失败结果);
- 成功:执⾏业务操作处理;
4. 业务操作完成后,把业务操作结果(成功/失败)发送给消息中间件;
5. 消息中间件收到业务操作结果后,根据业务结果进⾏处理;
- 失败:删除消息存储中的消息,结束;
- 成功:更新消息存储中的消息状态为“待发送(可发送)”,紧接着执⾏消息投递;
6. 前⾯的正向流程都成功后,向被动⽅应⽤投递消息;
4.4.2 异常场景
通过实现⼀定的机制,稳定可靠的保障在主动⽅处理完后准确地把消息传给消息消费被动⽅。
4.4.3 优点与适应场景
优点:
1. 降低主动⽅和被动⽅的耦合
2. 消息独⽴存储,利于扩展与伸缩
适应场景:
1. 内部跨系统的⼴播、短信通知
2. 第三⽅系统通知
4.5 ⼏种⽅案对⽐
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论