分布式事务柔性事务解决方案:可靠消息最终一致性(异步确保型) —— 二、生产者的设计

本方案分布式事务柔性事务解决方案:可靠消息最终一致性(异步确保型)实现自
龙果学院可靠消息最终一致性

本方案与龙果学院的方案思想基本一致,但本方案使用Spring Cloud实现
方案中用到的主要技术为: Spring Cloud、Spring Boot、MyBatis、JDK8、RabbitMQ

为什么要使用柔性事务

上篇文章已经详细说过,这里简单提下,传统的刚性事务无法满足高并发场景。而柔性事务可在牺牲一定的一致性、可用性、或者分区容错性的情况下,可以满足一定的高并发场景。

方案解构

这里写图片描述

生产者通过可靠消息服务将我们的消息发送给了消费者,就这么简单。对消息中间件有所了解的小伙伴应该就能看出这个图的不同了,它在生产者和可靠消息服务中间嵌入了一个可靠消息服务的角色,那么它起到什么样的作用呢?

可靠消息服务

假如我们没有使用可靠消息服务,会出现什么呢?(以下只是部分情况,不是所有情况)

  • 生产者将消息发送出去了,但是业务失败了
  • 生产者业务执行成功了,但是业务没有发送出去
  • 消息中间件消息丢失

我们的可靠消息服务就是为了解决这些问题而生。

伪TCC

为了确保消息的可靠,生产者向可靠消息服务投递消息时,我们这里采用伪TCC方式的模型。我们将消息分两步提交到可靠消息服务。它的本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败。

  • 第一步:预发送prepare。

生产者将消息发送到可靠消息服务,并将消息标记为待确认。

  • 第二步:确认发送confirm

可靠消息服务将消息标记为待发送,并将消息发送到MQ中。

(注:RocketMQ可直接支持这一特性)

扫描二维码关注公众号,回复: 2326417 查看本文章

这种伪TCC的消息事务可以保证消息投递的原子性。

这里写图片描述

  • 第一步,预发送消息
  • 第二步,得到预发送消息的回复
  • 第三步,执行业务
  • 第四步,确认消息发送
  • 第五步,得到确认消息发送的回复

在这个过程中,会有以下几种特殊情况:

  1. 如果第一、二步出现了异常,那么整个业务都不会执行,满足原子性。
  2. 如果第三步出现了异常,本地事务回滚,可靠消息服务收到了一条预发送消息,但它并不会将消息投递出去,满足原子性。
  3. 如果第四、五步出现了异常,确认发送出现异常,本地事务回滚,可靠消息服务收到了一条预发送消息,但它并不会将消息投递出去,满足原子性。

生产者的优化

单从模型上来说,最可行的优化方案就是减少网络传输带来的延迟,将生产者与可靠消息服务间的通信设为异步。当然,这样在一定的程度上会降低一致性。

异步确认消息

在异步的条件下,假设第四、五步因为网络不好没发出去,或者网络不好没接收到等情况,会出现业务执行成功,但消息依然未确认的情况。这个时候我们需要向可靠消息服务提供一个查询接口,用来查询业务执行的情况。

  • 在生产者中我们需要额外提供一个业务执行结果查询的接口。

可靠消息服务需要轮询出未确认的消息,向生产者查询,以便改变其状态。
这里写图片描述

这样,我们在调用生产者的时候,可以得到更快的响应。

  • 当可靠消息服务发现有未确认发送的消息时,会向生产者轮询这些消息,及时更新消息状态,并做出相应处理。
异步消息预发送

如果我们将消息的预发送也置为异步呢?

很简单,仿照上面的做法就行了。

这里写图片描述

这样一来,我们在请求执行业务时,不需要在网络传输上浪费时间,业务执行完毕,调用者就可以立刻得到响应。

猜你喜欢

转载自blog.csdn.net/anurnomeru/article/details/80306002