Java开发西安地区最近面试汇总(2020年4月)(一)

分布式事务的实现机制

什么是分布式事务

从单机系统扩展成分布式系统时,原有单机中相对可靠的方法调用以及进程内通信方式已经没有办法使用,同时由于网络通信经常是不稳定的,所以服务之间信息的传递会出现障碍
分布式事务是由于业务上的定义以及微服务架构设计的问题,所以需要在多个服务之间保证业务的事务性
模块(或服务)之间通信方式的改变是造成分布式事务复杂的最主要原因

分布式事务的两大理论依据

CAP定律

这个定理的内容是指的是在一个分布式系统中、Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

一致性(C)

在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)

可用性(A)

在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)

分区容错性(P)

以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

BASE理论

BASE是Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的缩写。BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结, 是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。

基本可用

基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性----注意,这绝不等价于系统不可用。比如:
(1)响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒
(2)系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面

软状态

软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时

最终一致性

最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

2PC(两阶段提交)

原理描述

两阶段提交是一种使分布式系统中所有节点在进行事务提交时保持一致性而设计的一种协议;在一个分布式系统中,所有的节点虽然都可以知道自己执行操作后的状态,但是无法知道其他节点执行操作的状态,在一个事务跨越多个系统时,就需要引入一个作为协调者的组件来统一掌控全部的节点并指示这些节点是否把操作结果进行真正的提交,想要在分布式系统中实现一致性的其他协议都是在两阶段提交的基础上做的改进
两阶段提交的执行过程分为投票阶段和提交阶段:

  • 投票阶段:**协调者(Coordinator)会向事务的参与者(Cohort)**询问是否可以执行操作的请求,并等待其他参与者的响应,参与者会执行相对应的事务操作并记录重做和回滚日志,所有执行成功的参与者会向协调者发送 AGREEMENT 或者 ABORT 表示执行操作的结果
  • 提交阶段:当所有的参与者都返回了确定的结果(同意或者终止)时,两阶段提交就进入了提交阶段,协调者会根据投票阶段的返回情况向所有的参与者发送提交或者回滚的指令。
    当事务的所有参与者都决定提交事务时,协调者会向参与者发送 COMMIT 请求,参与者在完成操作并释放资源之后向协调者返回完成消息,协调者在收到所有参与者的完成消息时会结束整个事务;与之相反,当有参与者决定 ABORT 当前事务时,协调者会向事务的参与者发送回滚请求,参与者会根据之前执行操作时的回滚日志对操作进行回滚并向协调者发送完成的消息,在提交阶段,无论当前事务被提交还是回滚,所有的资源都会被释放并且事务也一定会结束。

实现

MySQL 的 InnoDB 引擎其实能够支持分布式事务,也就是我们经常说的 XA 事务;XA 事务就是用了两阶段提交协议实现分布式事务,其中事务管理器为协调者,而资源管理器就是分布式事务的参与者

优点

尽量保证了数据的强一致。

缺陷

两阶段提交协议是一个阻塞协议,也就是说在两阶段提交的执行过程中,除此之外,如果事务的执行过程中协调者永久宕机,事务的一部分参与者将永远无法完成事务,它们会等待协调者发送 COMMIT 或者 ROLLBACK 消息,甚至会出现多个参与者状态不一致的问题。
简单归纳缺点如下,由于同步阻塞,所以不支持高并发。

  • 单点问题
  • 数据不一致
  • 同步阻塞

3PC(三阶段提交)

原理描述

为了解决两阶段提交在协议的一些问题,三阶段提交引入了超时机制准备阶段,如果协调者或者参与者在规定的之间内没有接受到来自其他节点的响应,就会根据当前的状态选择提交或者终止整个事务,准备阶段的引入其实让事务的参与者有了除回滚之外的其他选择。
在这里插入图片描述
当参与者向协调者发送 ACK 后,如果长时间没有得到协调者的响应,在默认情况下,参与者会自动将超时的事务进行提交,不会像两阶段提交中被阻塞住;上述的图片非常清楚地说明了在不同阶段,协调者或者参与者的超时会造成什么样的行为。

优点

通过超时机制解决了阻塞的问题

缺陷

三阶段提交也会导致数据一致性问题。由于网络原因,协调者发送的 abort 响应没有及时被参与者接收到,那么参与者在等待超时之后执行了 commit 操作。这样就和其他接到 abort 命令并执行回滚的参与者之间存在数据不一致的情况。

TCC协议

原理描述

TCC协议将一个任务拆分成Try、Confirm、Cancel
一个完整的业务活动由一个主业务服务于若干的从业务服务组成。主业务服务负责发起并完成整个业务活动。从业务服务提供TCC型业务操作。业务活动管理器控制业务活动的一致性,它登记业务活动的操作,并在业务活动提交时确认所有的TCC型操作的Confirm操作,在业务活动取消时调用所有TCC型操作的Cancel操作。
在这里插入图片描述
举个例子,假入 Bob 要向 Smith 转账,思路大概是:
我们有一个本地方法,里面依次调用
1、首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
2、在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
3、如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。

优点

不与具体的服务框架耦合,位于业务服务层,而不是资源层,可以灵活的选择业务资源的锁定粒度。TCC里对每个服务资源操作的是本地事务,数据被锁住的时间短,可扩展性好,可以说是为独立部署的SOA服务而设计的。

三种协议的一致性

两阶段提交协议、三阶段提交协议、TCC协议都能保证分布式事务的一致性,他们保证的分布式系统的一致性从强到弱,TCC达到的目标是最终一致性。

本地消息表(异步确保)

原理描述

  • 本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操作满足事务特性,并且使用了消息队列来保证最终一致性。
  • 在分布式事务操作的一方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中。
  • 之后将本地消息表中的消息转发到 Kafka 等消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。
  • 在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作。

优点

一种非常经典的实现,避免了分布式事务,实现了最终一致性。

缺点

消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

MQ 事务消息

原理描述

有一些第三方的MQ是支持事务消息的,比如RocketMQ,他们支持事务消息的方式也是类似于采用的二阶段提交,但是市面上一些主流的MQ都是不支持事务消息的,比如 RabbitMQ 和 Kafka 都不支持。
以阿里的 RocketMQ 中间件为例,其思路大致为:

  • 第一阶段Prepared消息,会拿到消息的地址。
  • 第二阶段执行本地事务,
  • 第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。

也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息发送失败了RocketMQ会定期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消息发送者确认,所以生产方需要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

优点

实现了最终一致性,不需要依赖本地数据库事务。

缺点

实现难度大,主流MQ不支持,RocketMQ事务消息部分代码也未开源。

原创文章 38 获赞 52 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yemuxiaweiliang/article/details/105860378