【分布式技术专题】「架构实践于案例分析」总结和盘点目前常用分布式事务特别及问题分析(中)

简介: 【分布式技术专题】「架构实践于案例分析」总结和盘点目前常用分布式事务特别及问题分析(中)

基于MQ的分布式事务(MQ事务最终一致性)


方案简介


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

image.png

本地消息表:最终一致性


方案简介


本地消息表的方案最初是由eBay提出,核心思路是将分布式事务拆分成本地事务进行处理。


  • 通过在事务主动发起方新建事务消息表事务发起方处理业务记录事务消息在本地事务中完成,轮询事务消息表的数据发送事务消息,事务被动方基于消息中间件消费事务消息表中的事务。
  • 这样设计可以避免”业务处理成功 + 事务消息发送失败",或"业务处理失败 + 事务消息发送成功"的棘手情况出现,保证 2 个系统事务的数据一致性。



处理流程


  • 把分布式事务最先开始处理的事务方称为事务主动方
  • 在事务主动方之后处理的业务内的其他事务称为事务被动方。



下面继续以电商下单为例进行方案解析,这里把整个过程简单分为扣减库存,订单创建 2 个步骤。



  1. 库存服务和订单服务分别在不同的服务器节点上,其中库存服务是事务主动方,订单服务是事务被动方


  1. 事务的主动方需要新建事务消息表,用于记录分布式事务的消息的发生、处理状态。



事务发起

image.png

事务回调

image.png



事务分布流程


步骤1-事务主动方处理本地事务。


  • 事务主动方在本地事务中处理业务更新操作和写消息表操作。

例:库存服务阶段在本地事务中完成扣减库存和写消息表



步骤 2-事务主动方通过消息中间件,通知事务被动方处理事务通知事务待消息。


  • 消息中间件可以基于 Kafka、RabbitMQ 消息队列,事务主动方主动写消息到消息队列,事务消费方消费并处理消息队列中的消息。

例:库存服务把事务待处理消息写到消息中间件,订单服务消费消息中间件的消息,完成新增订单



步骤 3-事务被动方通过消息中间件,通知事务主动方事务已处理的消息。


  • 为了数据的一致性,当处理错误需要重试,事务发送方和事务接收方相关业务处理需要支持幂等。

例,订单服务把事务已处理消息写到消息中间件,库存服务消费中间件的消息,并将事务消息的状态更新为已完成



保存一致性的容错处理


步骤 1 处理出错


事务回滚,相当于什么都没发生。



步骤2+步骤3处理出错


由于未处理的事务消息还是保存在事务发送方,事务发送方可以定时轮询为超时消息数据,再次发送到消息中间件进行处理。事务被动方消费事务消息重试处理

  • 如果业务上的失败事务被动方可以发消息给事务主动方进行回滚
  • 如果多个事务被动方已经消费消息事务主动方需要回滚事务时需要通知事务被动方回滚



方案总结


方案的优点


  • 从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对 MQ 中间件特性的依赖。
  • 方案轻量,容易实现。



方案的缺点


  1. 与具体的业务场景绑定,耦合性强,不可公用
  2. 消息数据与业务数据同库,占用业务系统资源
  3. 业务系统在使用关系型数据库的情况下,消息服务性能会受到关系型数据库并发性能的局限




基于RocketMQ的分布式事务(数据的最终一致性)


基于RocketMQ4.3之后的版本介绍 MQ 的分布式事务方案。


在本地消息表方案中,保证事务主动方发写业务表数据和写消息表数据的一致性是基于数据库事务,RocketMQ的事务消息相对于普通 MQ,相对于提供了 2PC 的提交接口,方案如下

image.png


正常情况:事务主动方发消息

image.png


事务主动方服务正常,没有发生故障,发消息流程如下:


  1. 发送方向 MQ 服务端(MQ Server)发送 half 消息。
  2. MQ Server 将消息持久化成功之后,向发送方 ack 确认消息已经发送成功。
  3. 发送方开始执行本地事务逻辑。
  4. 发送方根据本地事务执行结果向MQ Server 提交二次确认(commit 或是 rollback)。
  5. MQ Server 收到 commit 状态则将半消息标记为可投递订阅方最终将收到该消息MQ Server 收到 rollback 状态则删除半消息,订阅方将不会接受该消息



异常情况:事务主动方消息恢复

image.png

在断网或者应用重启等异常情况下,第四步提交的二次确认超时未到达 MQ Server,此时处理逻辑如下:


  1. MQ Server 对该消息发起消息回查。
  2. 发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
  3. 发送方根据检查得到的本地事务的最终状态再次提交二次确认。
  4. MQ Server基于 commit/rollback 对消息进行投递或者删除。



介绍完 RocketMQ 的事务消息方案后,由于前面已经介绍过本地消息表方案,这里就简单介绍 RocketMQ 分布式事务:

image.png


  • 事务主动方基于MQ通信通知事务被动方处理事务,事务被动方基于 MQ 返回处理结果。
  • 事务被动方消费消息异常,需要不断重试,业务处理逻辑需要保证幂等。
  • 事务被动方业务上的处理失败,可以通过 MQ 通知事务主动方进行补偿或者事务回滚。




方案总结


相比本地消息表方案,MQ 事务方案优点是:


  1. 消息数据独立存储 ,降低业务系统与消息系统之间的耦合。
  2. 吞吐量优于使用本地消息表方案。



缺点


  • **一次消息发送需要两次网络请求(half 消息 + commit/rollback 消息) **。
  • 业务处理服务需要实现消息状态回查接口。




相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
1天前
|
Java 持续交付 API
Java的分布式系统与微服务架构
Java的分布式系统与微服务架构
|
2天前
|
项目管理 微服务
拥抱不确定性:技术实践中的敏捷思维构建高效微服务架构:后端开发的新趋势
【5月更文挑战第29天】 在快速变化的技术世界中,不确定性已成为常态。本文探讨了如何在技术实践中运用敏捷思维来应对不确定性,提出了一套实用的策略和心态调整方法。通过案例分析,展示了在项目开发、系统设计以及团队协作中如何有效地应用敏捷原则,以适应需求变动、技术演进和市场波动。文章强调了持续学习、灵活适应和以人为本的管理对于维持技术实践敏捷性的重要性,旨在为技术人员提供一种面对不断变化环境的心智工具箱。
|
4天前
|
数据管理 测试技术 持续交付
构建高效微服务架构:策略与实践代码之美:简洁性与可读性的平衡艺术
【5月更文挑战第27天】在现代软件开发中,微服务架构已成为构建可扩展、灵活且容错的系统的首选方法。本文将探讨构建高效微服务架构的关键策略,包括服务划分、通信机制、数据管理以及持续集成与部署。通过实际案例分析,我们将讨论如何在实践中应用这些策略,以提高系统的性能和可靠性。 【5月更文挑战第27天】在软件开发的世界中,编写出既简洁又具有高可读性的代码是一种艺术。本文将探讨如何在保持代码简洁的同时,不牺牲其可读性和可维护性。我们将深入分析几个关键原则和实践技巧,并配以示例来阐明如何实现这种平衡。文章的目标是为开发者提供实用的指导,帮助他们在编码时做出明智的决策,以提升代码质量。
|
4天前
|
Java 测试技术 持续交付
Java中的异常处理机制探索自动化测试在微服务架构中的实践与挑战
【5月更文挑战第27天】本文将深入探讨Java中的异常处理机制,包括异常的概念、分类以及如何使用try-catch-finally语句进行异常处理。文章还将介绍自定义异常的方法以及在实际开发中如何选择合适的异常处理策略。 【5月更文挑战第27天】 随着软件开发领域向微服务架构的转型,传统的软件测试方法面临诸多挑战。本文旨在探讨自动化测试在微服务环境下的应用实践及所面临的问题。我们将从微服务的特性出发,分析自动化测试的必要性,并深入讨论如何构建一个高效、鲁棒的自动化测试框架。文章还将介绍一系列创新的测试策略和工具选择,以及如何克服微服务带来的分布式复杂性。最后,通过案例研究,展示自动化测试在实
|
4天前
|
消息中间件 缓存 数据库
构建高性能微服务架构:从理论到实践
【5月更文挑战第27天】在现代软件开发中,微服务架构已成为实现可扩展、灵活和容错系统的关键设计模式。本文将深入探讨如何构建一个高性能的微服务系统,包括关键的设计理念、技术选型以及性能优化策略。我们将通过分析真实案例,提供一套实用的指导原则和最佳实践,帮助开发者提升系统的响应速度和处理能力,从而满足不断变化的业务需求。
|
4天前
|
负载均衡 监控 API
探索后端开发中的微服务架构设计与实践
在当今快速发展的互联网时代,后端开发领域的微服务架构设计和实践变得愈发重要。本文将从微服务架构的概念、优势,以及设计和实施过程中的关键问题等方面展开探讨,带您深入了解后端开发中微服务架构的精髓。
12 0
|
4天前
|
Cloud Native 安全 持续交付
构建未来应用的基石:云原生架构的演进与实践
【5月更文挑战第27天】 在数字化转型的浪潮中,企业急需灵活、高效且可靠的解决方案以应对市场的快速变化。云原生架构应运而生,其不仅重塑了软件开发和运维的模式,也为企业提供了持续交付和自动化管理的可能性。本文将探讨云原生技术的发展历程,解析其关键组件如容器化、微服务及持续集成/持续部署(CI/CD),并分享如何在实践中有效利用这些技术来构建和维护高度可扩展的系统。
|
4天前
|
运维 Cloud Native 持续交付
构建未来:云原生架构的演进与实践
【5月更文挑战第27天】 随着数字化转型的深入,企业对于敏捷性、可扩展性和资源优化的需求日益增长。云原生技术以其独特的优势应运而生,并迅速成为推动现代应用开发和运维模式变革的关键力量。本文将探讨云原生架构的核心组件、实施策略以及在不断变化的技术环境中如何保持其演进和创新。通过深入分析容器化、微服务、持续集成/持续部署(CI/CD)及DevOps文化等关键技术,揭示构建和维护高效、弹性和安全的云原生系统的最佳实践。
|
4天前
|
敏捷开发 设计模式 前端开发
实践总结|前端架构设计的一点考究
本文总结了作者在日常/大促业务的“敏捷”开发过程中产生的疑惑,并尝试做出思考得到一些解决思路和方案。在前端开发和实践过程中,梳理了一些简单设计方案可以缓解当时 “头疼” 的几个敏捷迭代问题,并实践在项目迭代中。
|
4天前
|
监控 Cloud Native 持续交付
构建未来:云原生架构在现代企业中的应用与挑战构建高效微服务架构:策略与实践
【5月更文挑战第27天】 随着数字化转型的深入,企业对技术的依赖日益增强。云原生技术以其灵活性、可扩展性和敏捷性成为推动企业IT架构现代化的关键力量。本文将探讨云原生架构的核心概念、实施策略以及在采纳过程中可能遇到的挑战。通过分析案例和最佳实践,旨在为读者提供如何在保持业务连续性的同时,利用云原生技术加速创新的见解。 【5月更文挑战第27天】 在当前软件开发的快速迭代和市场需求多变的背景下,微服务架构以其灵活性、可扩展性和容错性成为企业技术选型的热门。本文将探讨如何构建一个高效的微服务系统,包括关键的设计原则、常用的技术栈选择、以及实施过程中的最佳实践。我们将重点分析如何通过合理的服务划分、
http://www.vxiaotou.com