【微服务】分布式事务的实现方法及替代方案

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 这两天正在研究微服务架构中分布式事务的处理方案, 做一个小小的总结, 作为备忘. 如有错误, 欢迎指正!概念澄清事务补偿机制: 在事务链中的任何一个正向事务操作, 都必须存在一个完全符合回滚规则的可逆事务.

这两天正在研究微服务架构中分布式事务的处理方案, 做一个小小的总结, 作为备忘. 如有错误, 欢迎指正!

概念澄清

事务补偿机制: 在事务链中的任何一个正向事务操作, 都必须存在一个完全符合回滚规则的可逆事务.

CAP理论: CAP(Consistency, Availability, Partition Tolerance), 阐述了一个分布式系统的三个主要方面, 只能同时择其二进行实现. 常见的有CP系统, AP系统.

幂等性: 简单的说, 业务操作支持重试, 不会产生不利影响. 常见的实现方式: 为消息额外增加唯一ID.

BASE(Basically avaliable, soft state, eventually consistent): 是分布式事务实现的一种理论标准.

柔性事务 vs. 刚性事务

刚性事务是指严格遵循ACID原则的事务, 例如单机环境下的数据库事务.

柔性事务是指遵循BASE理论的事务, 通常用在分布式环境中, 常见的实现方式有: 两阶段提交(2PC), TCC补偿型提交, 基于消息的异步确保型, 最大努力通知型.

通常对本地事务采用刚性事务, 分布式事务使用柔性事务.

最佳实践

先上结论, 再分别介绍分布式事务的各种实现方式.

如果业务场景需要强一致性, 那么尽量避免将它们放在不同服务中, 也就是尽量使用本地事务, 避免使用强一致性的分布式事务.

如果业务场景能够接受最终一致性, 那么最好是使用基于消息的最终一致性的方案(异步确保型)来解决.

如果业务场景需要强一致性, 并且只能够进行分布式服务部署, 那么最好是使用TCC方案而不是2PC方案来解决.

注意: 以下每种方案都有不同的适用场合, 需要根据实际业务场景来选择.

两阶段提交(2PC)

两阶段提交(Two Phase Commit, 2PC), 具有强一致性, 是CP系统的一种典型实现.

两阶段提交, 常见的标准是XA, JTA等. 例如Oracle的数据库支持XA.

下图是两阶段提交的示意图:

图的上半是两阶段提交成功的演示, 下半是两阶段提交失败的演示. 关于两阶段提交网上有很多经典的讲解, 这里就不细说了

缺点

两阶段提交中的第二阶段, 协调者需要等待所有参与者发出yes请求, 或者一个参与者发出no请求后, 才能执行提交或者中断操作. 这会造成长时间同时锁住多个资源, 造成性能瓶颈, 如果参与者有一个耗时长的操作, 性能损耗会更明显.

实现复杂, 不利于系统的扩展, 不推荐.

TCC (Try-Confirm-Cancle)

TCC, 是基于补偿型事务的AP系统的一种实现, 具有最终一致性.

下面以客户购买商品时的付款操作为例进行讲解:

Try: 

完成所有的业务检查(一致性),预留必须业务资源(准隔离性); 

体现在本例中, 就是确认客户账户余额足够支付(一致性), 锁住客户账户, 商户账户(准隔离性).

Confirm: 

使用Try阶段预留的业务资源执行业务(业务操作必须是幂等的), 如果执行出现异常, 要进行重试. 

在这里就是执行客户账户扣款, 商户账户入账操作.

Cancle: 

释放Try阶段预留的业务资源, 在这里就是释放客户账户和商户账户的锁; 

如果任一子业务在Confirm阶段有操作无法执行成功, 会造成对业务活动管理器的响应超时, 此时要对其他业务执行补偿性事务. 如果补偿操作执行也出现异常, 必须进行重试, 若实在无法执行成功, 则事务管理器必须能够感知到失败的操作, 进行log(用于事后人工进行补偿性事务操作或者交由中间件接管在之后进行补偿性事务操作).

优点

对比与前面提到的两阶段提交法, 有两大优势:

TCC能够对分布式事务中的各个资源进行分别锁定, 分别提交与释放, 例如, 假设有AB两个操作, 假设A操作耗时短, 那么A就能较快的完成自身的try-confirm-cancel流程, 释放资源. 无需等待B操作. 如果事后出现问题, 追加执行补偿性事务即可.

TCC是绑定在各个子业务上的(除了cancle中的全局回滚操作), 也就是各服务之间可以在一定程度上”异步并行”执行.

注意事项

事务管理器(协调器)这个节点必须以带同步复制语义的高可用集群(HAC)方式部署.

事务管理器(协调器)还需要使用多数派算法来避免集群发生脑裂问题.

适用场景

严格一致性

执行时间短

实时性要求高

举例: 红包, 收付款业务.

异步确保型

通过将一系列同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响.

这个方案真正实现了两个服务的解耦, 解耦的关键就是异步消息和补偿性事务.

这里以一个例子作为讲解:

执行步骤如下:

MQ发送方发送远程事务消息到MQ Server;

MQ Server给予响应, 表明事务消息已成功到达MQ Server.

MQ发送方Commit本地事务.

若本地事务Commit成功, 则通知MQ Server允许对应事务消息被消费; 若本地事务失败, 则通知MQ Server对应事务消息应被丢弃.

若MQ发送方超时未对MQ Server作出本地事务执行状态的反馈, 那么需要MQ Servfer向MQ发送方主动回查事务状态, 以决定事务消息是否能被消费.

当得知本地事务执行成功时, MQ Server允许MQ订阅方消费本条事务消息.

需要额外说明的一点, 就是事务消息投递到MQ订阅方后, 并不一定能够成功执行. 需要MQ订阅方主动给予消费反馈(ack)

如果MQ订阅方执行远程事务成功, 则给予消费成功的ack, 那么MQ Server可以安全将事务消息移除;

如果执行失败, MQ Server需要对消息重新投递, 直至消费成功.

注意事项

消息中间件在系统中扮演一个重要的角色, 所有的事务消息都需要通过它来传达, 所以消息中间件也需要支持 HAC 来确保事务消息不丢失.

根据业务逻辑的具体实现不同,还可能需要对消息中间件增加消息不重复, 不乱序等其它要求.

适用场景

执行周期较长

实时性要求不高

例如:

跨行转账/汇款业务(两个服务分别在不同的银行中)

退货/退款业务

财务, 账单统计业务(先发送到消息中间件, 然后进行批量记账)

最大努力通知型

这是分布式事务中要求最低的一种, 也可以通过消息中间件实现, 与前面异步确保型操作不同的一点是, 在消息由MQ Server投递到消费者之后, 允许在达到最大重试次数之后正常结束事务.

适用场景

交易结果消息的通知等.

小结

不管是同步事务中的事务管理器(协调者), 还是异步事务中使用的消息中间件,若要达到一致性保证,都需要使用带有同步复制语义的 HAC 提供的高可用和高可靠特性,这些都是以性能为代价的,无疑成为了SOA 架构中的典型性能瓶颈之一.

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
1月前
|
存储 消息中间件 Apache
比较微服务中的分布式事务模式
比较微服务中的分布式事务模式
46 2
|
27天前
|
存储 NoSQL Java
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
这篇文章是关于Java面试中的分布式架构问题的笔记,包括分布式架构下的Session共享方案、RPC和RMI的理解、分布式ID生成方案、分布式锁解决方案以及分布式事务解决方案。
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
|
14天前
|
监控 Go API
带你十天轻松搞定 Go 微服务之大结局(分布式事务)
带你十天轻松搞定 Go 微服务之大结局(分布式事务)
|
22天前
|
监控 Java 开发者
随着软件开发的发展,传统单体应用已难以适应现代业务需求,微服务架构因此兴起,成为构建可伸缩、分布式系统的主流
随着软件开发的发展,传统单体应用已难以适应现代业务需求,微服务架构因此兴起,成为构建可伸缩、分布式系统的主流。本文探讨Java微服务架构的设计原则与实践。核心思想是将应用拆分为独立服务单元,增强模块化与扩展性。Java开发者可利用Spring Boot等框架简化开发流程。设计时需遵循单一职责、自治性和面向接口编程的原则。以电商系统为例,将订单处理、商品管理和用户认证等拆分为独立服务,提高可维护性和容错能力。还需考虑服务间通信、数据一致性及监控等高级话题。掌握这些原则和工具,开发者能构建高效、可维护的微服务应用,更好地应对未来挑战。
60 1
|
23天前
|
JSON 算法 Java
微服务Token鉴权设计的几种方案
【8月更文挑战第18天】在微服务架构中,Token鉴权是确保服务安全性的重要环节。本文将详细介绍几种常见的微服务Token鉴权设计方案,旨在帮助大家在工作和学习中更好地理解和应用这些技术。
45 2
|
1月前
|
Cloud Native 云计算 微服务
云原生时代:企业分布式应用架构的惊人蜕变,从SOA到微服务的大逃亡!
【8月更文挑战第8天】在云计算与容器技术推动下,企业分布式应用架构正经历从SOA到微服务再到云原生的深刻变革。SOA强调服务重用与组合,通过标准化接口实现服务解耦;微服务以细粒度划分服务,增强系统灵活性;云原生架构借助容器化与自动化技术简化部署与管理。每一步演进都为企业带来新的技术挑战与机遇。
76 6
|
10天前
|
Java 数据库连接 微服务
揭秘微服务架构下的数据魔方:Hibernate如何玩转分布式持久化,实现秒级响应的秘密武器?
【8月更文挑战第31天】微服务架构通过将系统拆分成独立服务,提升了可维护性和扩展性,但也带来了数据一致性和事务管理等挑战。Hibernate 作为强大的 ORM 工具,在微服务中发挥关键作用,通过二级缓存和分布式事务支持,简化了对象关系映射,并提供了有效的持久化策略。其二级缓存机制减少数据库访问,提升性能;支持 JTA 保证跨服务事务一致性;乐观锁机制解决并发数据冲突。合理配置 Hibernate 可助力构建高效稳定的分布式系统。
23 0
|
14天前
|
消息中间件 SQL 关系型数据库
go-zero微服务实战系列(十、分布式事务如何实现)
go-zero微服务实战系列(十、分布式事务如何实现)
|
15天前
|
消息中间件 存储 Kafka
微服务实践之分布式定时任务
微服务实践之分布式定时任务
|
1月前
|
存储 监控 安全
下一篇
DDNS