微服务架构中分布式事务实现方案怎样何取舍

  

提起微服务架构,不可避免的两个话题就是服务治理和分布式事务。数据库和业务模块的垂直拆分为我们带来了系统性能,稳定性和开发效率的提升的同时也引入了一些更复杂的问题,例如在数据一致性问题上,我们不再能够依赖数据库的本地事务,对于一系列的跨库写入操作,如何保证其原子性,是微服务架构下不得不面对的问题。

  

1分布式事务解决方案

  

针对分布式系统的特点,基于不同的一致性需求产生了不同的分布式事务解决方案,追求强一致的两阶段提交,追求最终一致性的柔性事务和事务消息等等。各种方案没有绝对的好坏,抛开具体场景我们无法评价,更无法能做出合理选择。在选择分布式事务方案时,需要我们充分了解各种解决方案的原理和设计初衷,再结合实际的业务场景,从而做出科学合理的选择。

  

2强一致解决方案

  

2.1两阶段提交

  

两阶段提交算法中有两种角色:事务协调者和事务参与者,一个事务一般会涉及多个事务参与者,具体的两阶段过程如下图所示:

  

第一阶段:写库操作完成后协调者向所有参与者发送准备消息,询问各参与者的本地事务是否可以提交,参与者根据自身情况向协调者返回可以或不可以;

  

第二阶段:协调者收到所有参与者的反馈后,如果全部返回的是可以提交则向所有参与者发送提交事务命令只。要有一个参与者返回的是不能提交,则向所有参与者发送回滚命令。如下图所示:

  

  微服务架构中分布式事务实现方案怎样何取舍

  

图1,两阶段提交

  

在上述的两阶段模型中,事务提交过程中有可能出现协调者或个别参与者宕机的情况,但多数情况下参与事务的节点可以通过询问其他节点得知事务状态,做出正确的操作。但在极端情况下事务有可能处于未知状态。我们分析下下面这个场景:当协调者发送提交指令后宕机,而唯一收到提交指令的参与者完成提交后也宕机了,此时没有节点知道事务应该提交还是回滚,事务处于未知状态,所以在这种极端情况下可能造成数据的不一致。针对两阶段的缺陷,又提出了三阶段提交协议。

  

2.2,,三阶段提交

  

三阶段提交是将第二阶段拆分成预提交和确认提交两个阶段。这样在事务提交过程中,无论哪个节点宕机,只要有一个存活节点处于预提交或是提交状态我们都可以确定事务是可以提交的(第一阶段已经确认事务可以提交),反之如果没有处于这两种状态的节点,则回滚事务。

  

  微服务架构中分布式事务实现方案怎样何取舍

  

图2三阶段提交

  

从上面的分析可以看的到,无论是两阶段还是三阶段最后的“提交”都是一个耗时极短的操作,即使在分布式系统中失败的概率也是非常小的,所以我们可以认为两阶段提交基本能够保证分布式事务原子性。

  

3落地方案

  

上面介绍的只是理论基础,XA规范就是基于两阶段提交的理论模型提出的分布式事务规范,规范中的资源管理器相当于事务参与者;事务管理器相当于事务协调者,目前很多主流的关系数据库都实现了XA接口。

  

落地到实际应用中我们会发现两阶段提交存在的一些问题:

  

1只数据库产品要保证数据完成性,写入需要加锁,所以在整个分布式事务协调过程中可能造成数据库资源锁定时间过长,不适合并发高以及子事务生命周期较长的业务场景;

  

2。XA规范要求事务管理器本地记录事务执行状态,所以事务管理器作为有状态服务不支持事务异地恢复;

  

XA能够最大程度保证数据的一致性,但在高并发场景下性能衰减非常严重,所以在数据一致性需求上如果不是“强一致”,不建议使用。

  

3.1最终一致性解决方案

  

在我们大多数的业务场景中,追求的都是数据的最终一致性,业界也提出了很多柔性事务的解决方案,可以很大程度上保证数据的一致性,我们可以根据实际场景来权衡使用。具体的解决方案有很多,总结其设计思路可以分为下面3种模型:

  

3.1.1 移行细胞癌(Try-Confirm-Cancel)

  太极拳将

事务分为试,确认,取消三个阶段。

  

1只尝试阶段:尝试执行业务,预留资源;

  

微服务架构中分布式事务实现方案怎样何取舍