分布式柔性事务之事务消息详解

简介: 在 《柔性事务之TCC详解》 和《柔性事务之Saga详解》两文中我们详细剖析了柔性事务的第一个分支补偿型事务。在《刚性事务总结和柔性事务概述》中我们介绍过的柔性事务包含补偿型事务和通知型事务。
  • 消息详解 -

一、概述
在 《柔性事务之TCC详解》 和《柔性事务之Saga详解》两文中我们详细剖析了柔性事务的第一个分支补偿型事务。在《刚性事务总结和柔性事务概述》中我们介绍过的柔性事务包含补偿型事务和通知型事务。

通知型事务主要包含事务消息和最大努力通知型分布式事务两个组成。通知型事务的核心思想是通过MQ来通知其他事务参与者自己事务的执行状态。MQ组件的引入有效的将事务参与者解耦开,各个参与者都可以异步执行,所以通知型事务又称为异步事务。

事务消息的难度在于服务本地事务和投递消息的一致性保障。目前业界解决这个一致性的方案有两个分支:

基于MQ自身的事务消息方案
基于DB的本地消息表方案

  • 基于MQ自身的事务消息方案 -

基于MQ的事务消息方案主要依靠MQ的半消息机制来实现投递消息和参与者自身本地事务的一致性保障。半消息机制实现原理其实借鉴的2PC的思路,是二阶段提交的广义拓展,流程图如下:

attachments-2020-06-VfgahNdk5ef05c87a130a.png

1、事务发起方首先发送prepare消息到MQ;

2、在发送prepare消息成功后执行本地事务;

3、根据本地事务执行结果返回commit或者是rollback;

4、如果消息是rollback, MQ将删除该prepare消息不进行下发,如果是commit消息,MQ将会消息发送给consumer端;

5、如果执行本地事务过程中,执行端挂掉,或者超时,MQ服务器端将不停的询问producer来获取事务状态;

6、Consumer端的消费成功机制有MQ保证

MQ事务消息方案因为使用了半消息机制,对业务页具有比较大侵入性,有以下注意点:

1、 业务方调用半消息,并提供对应的回查方法;

2、 MQ提要提供半消息机制,并定期扫描长期半消息,对消息生产者进行回查确认事务。

3、 消费方需要进行幂等消费。

  • 基于BD的本地消息表方案 -

有时候我们目前的MQ组件并不支持事务消息,或者我们想尽量少的侵入业务方。这时我们需要另外一种方案“基于DB本地消息表“,流程图如下:

attachments-2020-06-I1HCABg25ef05ca527f47.png

1、 业务方:直接利用本地事务,将业务数据和事务消息直接写入数据库。

2、 投递线程:使用专门的投递工作线程进行事务消息投递到MQ,根据投递ACK去删除事务消息表记录

本地事务消息表的优势在于方案的通用性,无需提供回查方法,进一步减少的业务的侵入。在某些场景下,还可以进一步利用注解等形式进行解耦,有可能实现无业务代码侵入式的实现。我们上面说了本地事务消息表的基本理论,那么如果要设计一个高可用的企业级本地事务消息表方案,就要考虑更多的事情,在性能上做更大的优化,降低更多的重复投递率。以下是一个企业级事务消息的设计流程图:

attachments-2020-06-3vH4McP95ef05cb24486c.png

1、 事务消息服务:提供通用投递接口,用于保证事务消息的本地写入,并将事务消息写入事务内存队列。

2、 使用投递线程池,继续事务内存队列投递派发分配。投递工作线程只投递本实例拥有的事务消息,投递失败线程列入时间轮队列;重试机制使用失败挡位区分,默认提供6档:5s、10s、15s、20s、25s、30s。

3、 时间轮线程进行60秒转动,将到期的失败事务消息重入事务内存队列.

4、 因为我们的事务消息服务是无状态化的多实例存在,所以需要一个持锁线程进行主节点竞争强锁,处理一些额外的工作。

5、 因为我们的事务内存队列是内存级,不可避免面临重启等情况下的数据丢失。这时需要事务消息服务主节点进行定期扫表,将长期未投递的事务消息取出放入事务消息服务。

6、 事务消息服务主节点还有一个清理线程,专门用于将已处理成功的历史事务消息进行归档清理,降低DB的数据量。

  • 总结 -

咱们上面介绍了MQ事务消息方案和DB本地消息表方案,这两个方案有什么区别呢?

1、 MQ事务消息方案

a) 需要MQ支持半消息机制或者类似特性,在重复投递上具有比较好的去重处理

b) 需要业务方进行改造,提供对应的本地操作成功回查功能。具有比较大的业务侵入性。

2、 DB本地事务消息表方案

a) 使用了数据库来存储事务消息,降低了对MQ的需求,但是增加了存储成本。

b) 事务消息使用了异步投递,增大了消息重复投递的可能性。

我们说了两种事务消息的特性和优劣性,我们在总结下事务消息的共性。

1、 事务消息都依赖MQ进行事务通知,所以都是异步的。

2、 事务消息在投递方都是存在重复投递的可能,需要有配套的机制去降低重复投递率,实现更友好的消息投递去重。

3、 事务消息的消费方,因为投递重复的无法避免,因此需要进行消费去重设计或者服务幂等设计。

本文来源于:奈学开发者社区  

如有侵权请联系我删除。

相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
6月前
|
运维 监控 Java
Spring Cloud Alibaba分布式事务问题之事务commit失败如何解决
Spring Cloud Alibaba提供了一套在Spring Cloud框架基础上构建的微服务解决方案,旨在简化分布式系统的开发和管理;本合集将探讨Spring Cloud Alibaba在实际应用中的部署和使用技巧,以及该框架常见问题的诊断方法和解决步骤。
|
6月前
|
消息中间件 Dubbo 应用服务中间件
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
196 0
|
22天前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
10天前
|
监控
Saga模式在分布式系统中保证事务的隔离性
Saga模式在分布式系统中保证事务的隔离性
|
2月前
Saga模式在分布式系统中如何保证事务的隔离性
Saga模式在分布式系统中如何保证事务的隔离性
|
4月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中与事务隔离级别结合使用
乐观锁在分布式数据库中与事务隔离级别结合使用
|
6月前
|
消息中间件 Java 关系型数据库
Spring事务与分布式事务
这篇文档介绍了事务的概念和数据库事务的ACID特性:原子性、一致性、隔离性和持久性。在并发环境下,事务可能出现更新丢失、脏读和不可重复读等问题,这些问题通过设置事务隔离级别(如读未提交、读已提交、可重复读和序列化)来解决。Spring事务传播行为有七种模式,影响嵌套事务的执行方式。`@Transactional`注解用于管理事务,其属性包括传播行为、隔离级别、超时和只读等。最后提到了分布式事务,分为跨库和跨服务两种情况,跨服务的分布式事务通常通过最终一致性策略,如消息队列实现。
69 0
|
6月前
|
消息中间件 RocketMQ 微服务
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)(下)
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
196 1
|
6月前
|
消息中间件 RocketMQ Docker
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)
91 0

热门文章

最新文章

下一篇
无影云桌面