分布式事务(延时队列RabbitMQ)

动态每日更新算法题,想要学习的可以关注一下


一、分布式事务

1.什么是分布式事务

分布式事务(Distributed transaction):是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。一个大的操作由 N 多的小的操作共同完成,而这些小的操作又分布在不同的服务上。针对于这些操作,要么全部成功执行,要么全部不执行。

在这里插入图片描述

其实很简单:就是在分布式的场景下使用事务回滚机制,要么全部成功,要么全部不执行。

2.业务场景

在这里插入图片描述

其实很简单,就是我们在分布式场景下肯定避免不了远程服务的调用,最常见的就是feign的远程调用。

	@Transactional
	productService(){
		/**
			其他业务操作
		**/
		wareService();
		int i= 10/0;

}

在10/0肯定会抛出异常,那么因为加了本地事务,productService肯定会回滚,但是wareService属于远程服务进而不会回滚。

3.CAP 定理

在一个分布式系统中,以下三点特性无法同时满足(号称 CAP “不可能三角”):

在这里插入图片描述

C:Consistency,一致性。在分布式系统中的所有数据备份,「在同一时刻具有同样的值」,所有节点在同一时刻读取的数据都是最新的数据副本(等同于所有节点访问同一份最新的数据副本)。
A:Availability,可用性,好的响应性能。完全的可用性指的是在「任何故障模型(集群系统中部分节点故障)下,服务都会在有限的时间内处理完成并进行响应」(对数据更新具备高可用性)。
P:Partition tolerance,分区容忍性。尽管网络上有部分消息丢失或者服务不可用,但系统仍然可继续工作、继续操作。
具体地讲在分布式系统中,在任何数据库设计中,一个 Web 应用 「至多只能同时支持上面的两个属性」。显然,任何横向扩展策略都要依赖于 数据分区。因此,设计人员必须在 一致性 与 可用性 之间做出选择:

任何分布式系统,必须依赖 P(Partition tolerance,分区容忍性)。
分布式系统可选性,要么 CP(强一致性),要么 AP(弱一致性,也叫最终一致性),三者不可兼具。
单体系统中的事务一致性,即为 AC 组合。表现为不拆分数据系统,在一个数据库的一个事务中完成所有的操作。

4.BASE 理论

在这里插入图片描述

在分布式系统中,更多追求的是可用性,它的权重比一致性要高,如何实现高可用性?那就是 BASE 理论,它是用来对 CAP 定理进行进一步扩充的。BASE 理论解决 CAP 理论提出了分布式系统的一致性和可用性不能兼得的问题。

“酸碱” 平衡理论
BASE 在英文中有 “(base)碱” 的意思,对应本篇开头的 ACID 在英文中 “(acid)酸” 的意思,基于这两个名词提出了 酸碱平衡 的结论。简单来说是 在不同的场景下,可以分别利用 ACID 和 BASE 来解决分布式服务化系统的一致性问题。

BASE 模型与 ACID 模型截然不同,满足 CAP 理论,通过牺牲强一致性,获得可用性,一般应用在服务化系统的应用层或者大数据处理系统,通过达到 最终一致性 来尽量满足业务的绝大部分需求。

(1)BASE 理论三要素

BASE 理论模型包含个三个元素:

BA:Basically Available(基本可用),系统出现了不可预知的故障,但还是能用,相比较正常的系统而言会有响应时间上的损失和功能上的损失。
S:Soft state(软状态),状态可以有一段时间不同步。
E:Eventually consistent(最终一致性),最终态数据是一致的就可以了,而不是时时保持强一致。
BASE 理论是对 CAP 中的 一致性(CP) 和 可用性(AP) 进行一个权衡的结果,理论的核心思想就是:无法做到 强一致性(CP) ,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到 最终一致性(Eventual consistency)。

(2)什么是软状态呢?

相对于 原子性(ACID) 而言,要求多个节点的数据副本都是一致的,这种也称为 “硬状态”。

“软状态” 指的是:允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延时同步。当然不可能一直是软状态,必须有个时间期限。在期限过后,应当保证所有副本保持数据一致性,从而达到数据的 最终一致性 (最终态)。这个 时间期限取决于网络延时、系统负载、数据复制方案设计等等因素。

(3)最终一致性分类

在实际工程实践中,最终一致性分为 5 种:

因果一致性(Causal consistency),如果节点A在更新完某个数据后通知了节点B,那么节点B之后对该数据的访问和修改都是基于A更新后的值。于此同时,和节点A无因果关系的节点C的数据访问则没有这样的限制。
读己之所写一致性(Read-your-writes consistency),节点A更新一个数据后,它自身总是能访问到自身更新过的最新值,而不会看到旧值。其实也算一种因果一致性。
会话一致性(Session consistency),会话一致性将对系统数据的访问过程框定在了一个会话当中:系统能保证在同一个有效的会话中实现 “读己之所写” 的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。
单调读一致性(Monotonic read consistency),如果一个节点从系统中读取出一个数据项的某个值后,那么系统对于该节点后续的任何数据访问都不应该返回更旧的值。
单调写一致性(Monotonic write consistency),一个系统要能够保证来自同一个节点的写操作被顺序的执行。
在实际的实践中,这 5 种类型往往会结合使用,以构建一个具有最终一致性的分布式系统。

BASE 模型的 软状态(Soft state) 是实现 BASE 理论的方法,基本可用(BA) 和 最终一致(E) 是目标。按照 BASE 模型实现的系统,由于不保证强一致性,系统在处理请求的过程中,可以存在短暂的不一致,在短暂的不一致窗口请求处理处在临时状态中,系统在做每步操作的时候,通过记录每一个临时状态,在系统出现故障的时候,可以从这些中间状态继续未完成的请求处理或者退回到原始状态,最后达到一致的状态。

二、解决方案

1. 2PC(简单了解)

2PC 即两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase),2 是指两个阶段,P 是指准备阶段,C 是指提交阶段。

举例:张三和李四好久不见,老友约起聚餐,饭店老板要求先买单,才能出票。这时张三和李四分别抱怨近况不如意,囊中羞涩,都不愿意请客,这时只能AA。只有张三和李四都付款,老板才能出票安排就餐。但由于张三和李四都是铁公鸡,形成了尴尬的一幕:

准备阶段:老板要求张三付款,张三付款。老板要求李四付款,李四付款。

提交阶段:老板出票,两人拿票纷纷落座就餐。

例子中形成了一个事务,若张三或李四其中一人拒绝付款,或钱不够,店老板都不会给出票,并且会把已收款退回。

整个事务过程由事务管理器和参与者组成,店老板就是事务管理器,张三、李四就是事务参与者,事务管理器负责决策整个分布式事务的提交和回滚,事务参与者负责自己本地事务的提交和回滚。

2.Seata 方案(不推荐不适用于高并发场景)

Seata 把一个分布式事务理解成一个包含了若干分支事务的全局事务。全局事务的职责是协调其下管辖的分支事务达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个关系数据库的本地事务。
在这里插入图片描述

Transaction Coordinator(TC):事务协调器,它是独立的中间件,需要独立部署运行,它维护全局事务的运行状态,接收 TM 指令发起全局事务的提交与回滚,负责与 RM 通信协调各各分支事务的提交或回滚。
Transaction Manager(TM): 事务管理器,TM 需要嵌入应用程序中工作,它负责开启一个全局事务,并最终向 TC 发起全局提交或全局回滚的指令。
Resource Manager(RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器 TC 的指令,驱动分支(本地)事务的提交和回滚。

3.可靠消息最终一致性(推荐)

可靠消息最终一致性方案是指当事务发起方执行完成本地事务后并发出一条消息,事务参与方(消息消费者)一定能够接收消息并处理事务成功,此方案强调的是只要消息发给事务参与方最终事务要达到一致。

此方案是利用消息中间件完成,如下图:

在这里插入图片描述

事务发起方(消息生产方)将消息发给消息中间件,事务参与方从消息中间件接收消息,事务发起方和消息中间件之间,事务参与方(消息消费方)和消息中间件之间都是通过网络通信,由于网络通信的不确定性会导致分布式事务问题。 在这里介绍RabbitMQ作为消息中间件。

3.RabbitMQ

1. RabbitMQ介绍即安装

RabbitMQ介绍和安装以及当下发展现状

2.延时队列

1.死信队列

在这里插入图片描述

需要注意的是,死信队列不会被任何服务所监听。

2.延时队列场景

在这里插入图片描述

如上图所示,下订单之后将会立马会进行锁库存,但是如果订单超过30min没有支付,那么订单会自动关闭,接着就必须进行解锁库存的操作。
具体做法可以是:

  1. 下订单,向死信队列中发送订单消息,消息存活时间为30min。
  2. 30min之后消息过期时,会自动向一个交换机发送消息,经由交换机转发到服务队列(被库存服务监听)。
  3. 库存服务拿到订单,如id或者订单号之后会去数据库中查询,如果订单已经不存在,则进行解库存。

在这里插入图片描述

需要注意的是死信队列会根据死信路由发送给一个交换机,这个交换机和别的其实没有什么不一样。

总结

其实总体流程很简单,这里总结一下。

  1. 下订单,锁库存,且向死信队列发送消息
  2. 30min后死信队列会路由给一个交换机且会带上一个路由键,经由交换机转发给服务监听的队列。
  3. 服务拿到消息去数据库中确认,如果订单存在则不需要操作,如果订单不存在则会进行解库存。

这里说一下如何解库存,其实就是将这个订单的各种数据用一张新表,订单id,商品id,商品数量存入到数据库中,如果库存服务没有查到该订单号就会根据订单id查到这个订单 然后再把相应的数量加到原来的库存数据库中。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值