SpringBoot_第九章(CAP和分布式事务)

目录

1:什么是CAP

2:分布式事务

3:分布式事务解决方案

3.1:2PC的分布式事务解决方案

3.2:3PC的分布式事务解决方案

3.3:TCC(事务补偿)

3.4:MQ事务方案(可靠消息事务)

3.5:Seata分布式事务


1:什么是CAP

在分布式的网络环境中,存在了网络分区,比如大型电商项目,下单模块和减库存模块会分开部署,那么下单后去扣减库存就存在了问题。

先来了解CAP定理:

C:(consistency) 表示一致性,所有节点在同一时间的数据保持完全一致。

A:(Availability)表示可用性,用户访问数据的时候,系统是否能在正常响应时间返回预期的结果。

P:  (Partition tolerance) 表示分区容错性,代表分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务

我们用电商系统的下单和减库存来具体说明CAP原理

SpringBoot_第九章(CAP和分布式事务)_第1张图片

在订单和减库存的两个服务中,首先用户下单会创建订单然后调用扣减库存系统,扣减库存。但是两个系统存在不同的服务器上,通过网络通信,就可能存在通信失败的情况,或者减库存系统停机。

这个时候就存在了P(分区容错性)。我们怎么选择CP和AP呢?

CP:保证强一致性的,如果下单成功必须要等待口减库存也成功。在高并发下可能会卡顿,后者库存系统停机,就不能下单了。用户体验较差,保证了强一致性。

AP: 保证了系统了高可用性,比如下单成功后,不等待口减库存成功,异步扣减库存。保证了高可用性。用户体验好,但是可能出现数据不一致问题。

CA: 不存在分区容错性,保证一致性和高可用,那就是传统的大单体架构。在一个数据库中完成下单和减库存。既能保证同一个事务的一致性和可用性。

总结:在分布式架构中我们怎么选择?

比如电商项目的下单减库存:可以选择AP,保证高可用,保住用户体验。牺牲强一致性。

但是在银行项目中和12306抢火车票的项目中,我们经常发现下单之后很卡,等待一小会就会出现票已经卖光了(下单减库存强一致)。这就是CP架构。保证了数据的强一致性。但是牺牲了一些可用性。

总得来说要根据安全和业务来选择AP或者CP。

2:分布式事务

什么是是分布式事务

我们知道在单机下边的事务通过注解开启事务。但是在分布式的系统中,比如扣减订单和减库存

客户在主业务中,发起了下单和减库存两个服务,这两个服务在不同的服务器上,我们该怎么保证事务的一致性呢?

SpringBoot_第九章(CAP和分布式事务)_第2张图片

正常情况下,下单和扣减库存都成功,两边保证了数据的一致性。

SpringBoot_第九章(CAP和分布式事务)_第3张图片

但是不正常情况下的,比如下单模块失败或者是超时。导致了库存扣减成功后,下单失败。两边就有了一致性问题,出现了数据不一致。我们无法通过单机的事务来控制。于是就有了分布式事务的问题。

SpringBoot_第九章(CAP和分布式事务)_第4张图片

3:分布式事务解决方案

3.1:2PC的分布式事务解决方案

2PC:是两阶段提交协议的缩写

第一阶段:事务协调者询问各个服务是否可以提交事务

SpringBoot_第九章(CAP和分布式事务)_第5张图片

1:参与者接收到执行本地的操作,记录undo和redo日志,但是不提交事务 

2:如果参与者执行成功后者失败,回消息给事务协调者commit提交或者rollback回滚

第二阶段:事务协调者根据参与者的反馈,如果都能提交,才会发送commit命令,否则你们都他丫的给我回滚。

SpringBoot_第九章(CAP和分布式事务)_第6张图片

这个时候各个参与者根据接收到事务协调者的命令来提交或者回滚(根据undo日志回滚),并且执行完毕后发送ack确认给事务协调者,协调者结束本次分布式事务。

2PC的缺点总结:

1:必须要有一个协调者,并且依赖协调者的高可用,协调者不能出问题,否则事务不释放。

2:在第二阶段数据的事务提交的过程中,可能会出现事务协调者告诉参与者你们都可以提交事务的时候,有的参与者没接收到,就没有提交,但是其他的参与者提交的事务,但是数据不一致。

3:大体上保证了在整个分布式事务的过程中数据一致,不保证强一致性

3.2:3PC的分布式事务解决方案

3PC:就是3段式提交的缩写

主要就是优化了2PC的第二阶段的缺点,比如存在事务协调者告知参与者提交事务,但是有的参与者没收到提交命令,导致没有提交事务,但是其他的参与者提交了事务,导致数据不一致。

3PC相比于2PC的主要提升点就是两个改进点

1:添加了超时机制

2:在第一阶段和第二阶段之间添加了一个准备阶段

第一阶段:CanCommit 准备阶段

协调者向多个参与者发送是否可以提交的命令,如果收到了都可以提交,进行到下一个准备提交阶段,否则事务取消

SpringBoot_第九章(CAP和分布式事务)_第7张图片

第二阶段:PreCommit 阶段

协调者收到收到可以提交事务的命令,记录undo和redo日志,返回给协调者ack命令,向参与者发送准备提交的命令,参与者收到命令。如果参与者给协调者发送ack命令超时。那么参与者中断事务,任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。

SpringBoot_第九章(CAP和分布式事务)_第8张图片

第三阶段:doCommit阶段

进入阶段 3 后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的 do Commit 请求或 abort 请求。此时,参与者都会在等待超时之后,继续执行事务提交。

协调者发送真正的提交命令,各个参与者会提交事务,提交后释放资源。当在参与者收到 preCommit 请求后等待 doCommit 指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

SpringBoot_第九章(CAP和分布式事务)_第9张图片

这是第三阶段的中断操作

SpringBoot_第九章(CAP和分布式事务)_第10张图片

3PC的优缺点:

相较于2PC,增加的超时机制,超时的情况的会释放事务,取消操作。增加了数据的一致性

数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 doCommit 指令时,此时如果协调者请求中断事务,而协调者因为网络问题无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

3.3:TCC(事务补偿)

神马事TCC?

TCC(Try Confirm Cancel):尝试、确认、取消机制,是一种侵入业务的代码解决方案。是最火的解方案。

也就是说每一个接口都要有三个扩展,try尝试模块,confirm确认模块,cancel取消模块。

TCC分为两个阶段,分别如下:

第一阶段:Try(尝试),主要是对业务系统做检测及资源预留 (加锁,锁住资源)

第二阶段:本阶段根据第一阶段的结果,决定是执行confirm还是cancel

Confirm(确认):执行真正的业务(执行业务,释放锁)

Cancle(取消):是预留资源的取消(出问题,释放锁)
 

业务案例说明:

考虑最简单的情况:我们有了转机的需求,曲线回家。美团先去川航帮我买票,如果买不到,那么东航也没必要买了。如果川航购买成功,再去东航购买另一张票。

现在问题来了:假设美团先从川航成功买到了票,然后去东航买票的时候,因为天气问题,东航航班被取消了。那么此时,美团必须取消川航的票,因为只有一张票是没用的,不取消就是浪费我的钱。那么如果取消会怎样呢?如果读者有取消机票经历的话,非正常退票,肯定要扣手续费的。在这里,川航本来已经购买成功,现在因为东航的原因要退川航的票,川航应该是要扣代理商的钱的。

那么美团就要保证,如果任一航班购买失败,都不能扣钱,怎么做呢?

两个航空公司都为美团提供以下3个接口:机票预留接口、确认接口、取消接口。美团App分2个阶段进行调用,如下所示:

SpringBoot_第九章(CAP和分布式事务)_第11张图片

TCC方案总结:


优点:TCC 事务机制相对于传统事务机制(X/Open XA),TCC 事务机制相比于上面介绍的 XA 事务机制,有以下优点:

性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源。

数据最终一致性:基于 Confirm 和 Cancel 的幂等性,保证事务最终完成确认或者取消,保证数据的一致性。

可靠性:解决了 XA 协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器也变成多点,引入集群。

缺点:TCC 的 Try、Confirm 和 Cancel 操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本。

3.4:MQ事务方案(可靠消息事务)

基于 MQ 的分布式事务方案其实是对本地消息表的封装,将本地消息表基于 MQ 内部,其他方面的协议基本与本地消息表一致。

MQ事务方案整体流程和本地消息表的流程很相似,如下图:

SpringBoot_第九章(CAP和分布式事务)_第12张图片

1:业务代码向mq发送half消息,mq把消息持久化到mq的服务器,回复ack

2:业务代码执行本地事务

3:发送方根据本地事务执行结果向 MQ Server 提交二次确认(commit 或是 rollback)。

4:MQ Server 收到 commit 状态则将半消息标记为可投递,订阅方最终将收到该消息;MQ Server 收到 rollback 状态则删除半消息,订阅方将不会接受该消息。

MQ的优点

消息数据独立存储 ,降低业务系统与消息系统之间的耦合。

吞吐量大于使用本地消息表方案。

缺点
一次消息发送需要两次网络请求(half 消息 + commit/rollback 消息) 。

业务处理服务需要实现消息状态回查接口。
 

3.5:Seata分布式事务

你可能感兴趣的:(框架_SpringBoot,分布式)