微服务架构分布式事务设计方案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
微服务- 分布式事务概念澄清
事务补偿机制:在事务链中的任何一个正向事务操作,都必须存在一个完全符合回
滚规则的可逆事务.
CAP理论:CAP(Consistency, Availability, Partition Toleranee), 阐述了一个分布式系统的三个主要方面,只能同时择其二进行实现•常见的有CP系统,AP系
统.
幂等性:简单的说,?业务操作支持重试,不会产生不利影响.常见的实现方式:为消息额外增加唯一 ID.
BASEBasically avaliable, soft state, eve ntually con siste nt): 是分布式事务实现的一种理论标准.
柔性事务vs.刚性事务
刚性事务是指严格遵循 ACID原则的事务,例如单机环境下的数据库事务.
柔性事务是指遵循 BASE S论的事务,通常用在分布式环境中,常见的实现方式有:
两阶段提交(2PC), TCC补偿型提交,基于消息的异步确保型,最大努力通知型. 通常对本地事务采用刚性事务,分布式事务使用柔性事务.
最佳实践
先上结论,再分别介绍分布式事务的各种实现方式如果业务场景需要强一致性,那么尽量避免将它们放在不同服务中,也就是尽量使用本地事务,避免使用强一致性的分布式事务•
如果业务场景能够接受最终一致性,那么最好是使用基于消息的最终一致性的方案
(异步确保型)来解决•
如果业务场景需要强一致性,并且只能够进行分布式服务部署,那么最好是使用 TCC方案而不是2PC方案来解决.
注意:以下每种方案都有不同的适用场合,需要根据实际业务场景来选择•
两阶段提交(2PC)
两阶段提交(Two Phase Commit, 2PC), 具有强一致性,是CP系统的一种典型实
现.
两阶段提交,常见的标准是XA, JTA等.例如Oracle的数据库支持XA.
示意图
图的上半是两阶段提交成功的演示,下半是两阶段提交失败的演示•关于两阶段提交网上有很多经典的讲解,这里就不细说了,可以参考前面的链接•
缺点
两阶段提交中的第二阶段,协调者需要等待所有参与者发出yes请求,或者一个参
与者发出no请求后,才能执行提交或者中断操作.这会造成长时间同时锁住多个资源,造成性能瓶颈,如果参与者有一个耗时长的操作,性能损耗会更明显.
实现复杂,不利于系统的扩展,不推荐.
TCC (Try-C on firm-Ca ncle)
TCC,是基于补偿型事务的 AP系统的一种实现,具有最终一致性.
下面以客户购买商品时的付款操作为例进行讲解:
Try:?
完成所有的业务检查(一致性),预留必须业务资源(准隔离性);?
体现在本例中,就是确认客户账户余额足够支付(一致性),锁住客户账户,商户账户(准隔离性).
Con firm:?
使用Try阶段预留的业务资源执行业务(业务操作必须是幂等的),如果执行出现异常,要进行重试.?
在这里就是执行客户账户扣款,商户账户入账操作•
Can cle:?
释放Try阶段预留的业务资源,在这里就是释放客户账户和商户账户的锁;?
如果任一子业务在Confirm阶段有操作无法执行成功,会造成对业务活动管理器的响应超时,此时要对其他业务执行补偿性事务.如果补偿操作执行也出现异常,必须进行重试,若实在无法执行成功,则事务管理器必须能够感知到失败的操作,进
行log(用于事后人工进行补偿性事务操作或者交由中间件接管在之后进行补偿性事务操作).
优点
对比与前面提到的两阶段提交法,有两大优势:
TCC能够对分布式事务中的各个资源进行分别锁定,分别提交与释放,?例如,假设有AB两个操作,假设A操作耗时短,那么A就能较快的完成自身的
try-confirm-cancel 流程,释放资源.无需等待B操作.如果事后出现问题,追加
执行补偿性事务即可.
TCC是绑定在各个子业务上的(除了 cancle中的全局回滚操作),也就是各服务之间可以在一定程度上”异步并行”执行
注意事项
事务管理器(协调器)这个节点必须以带同步复制语义的高可用集群(HAC)方式部署. 事务管理器(协调器)还需要使用多数派算法来避免集群发生脑裂问题.
适用场景
严格一致性
执行时间短
实时性要求高
举例:红包,收付款业务.
异步确保型
通过将一系列同步的事务操作变为基于消息执行的异步操作,避免了分布式事务中的同步阻塞操作的影响•
这个方案真正实现了两个服务的解耦,解耦的关键就是异步消息和补偿性事务•这里以一个例子作为讲解:
执行步骤如下:
1. MC发送方发送远程事务消息到 MQ Server;
2. MQ Server给予响应,表明事务消息已成功到达 MQ Server.
3. MC发送方Commit本地事务.
4. 若本地事务Commit成功,则通知MQServer允许对应事务消息被消费;若本地事务
失败,则通知MQ Server对应事务消息应被丢弃.
5. 若MQ发送方超时未对 MQ Server作出本地事务执行状态的反馈,那么需要MQ
Servfer向MC发送方主动回查事务状态,以决定事务消息是否能被消费.
6. 当得知本地事务执行成功时,MQ Server允许MC订阅方消费本条事务消息.
需要额外说明的一点,就是事务消息投递到 MC订阅方后,并不一定能够成功执行. 需要MC订阅方主动给予消费反馈(ack)
如果MC订阅方执行远程事务成功,则给予消费成功的ack,那么MQ Server可以安全将事务消息移除;
如果执行失败,MQ Server需要对消息重新投递,直至消费成功.
注意事项
消息中间件在系统中扮演一个重要的角色,所有的事务消息都需要通过它来传达,所以消息中间件也需要支持 HAC来确保事务消息不丢失.
根据业务逻辑的具体实现不同,还可能需要对消息中间件增加消息不重复,不乱序等其它要求•
适用场景
执行周期较长
实时性要求不高
例如:
跨行转账/汇款业务(两个服务分别在不同的银行中)