基于消息中间件的分布式事务

前言

此文来源于个人博客网站:http://51think.net面试

关于分布式事务的实现,网上有不少解说,固然这也是面试官的常备面试题。不少朋友在工做中不多接触到分布式事务,认为这个玩意交互太多,不必。其实我也是这么想的,想要完成一个完整的分布式事务链路,通讯开销实在太多。而现现在,微服务架构在行业内大行其道,巴不得全部模块都用上微服务来管理,而不知道本身已经慢慢失去了对软件控制的能力,从数据层面上来讲,咱们下降了对数据一致性控制的能力。既然市场上很流行,咱们仍是须要了解一下的,借此,本文介绍一下基于消息中间件的分布式事务的原理。服务器

1、核心思想

了解分布式事务,咱们须要抓住几个重点。我总结了一下,能够称之为232法则,即两个角色,三个阶段,两个结果。两个角色是指系统中要存在协调者角色和参与者角色,本文中消息服务器充当协调者,客户端和服务端充当参与者;三个阶段是指分布式事务能够分为预提交阶段,提交阶段,撤销阶段。两个结果是指,参与者中的执行操做要么所有执行,要么所有失败,不能出现部分红功部分失败的状况。 网络

基于消息服务器的分布式事务,咱们须要将事务划分红两个部分,一个是客户端与消息服务器交互的提交部分,一个是服务端与消息服务器交互的消费部分。咱们须要保证两点:
一、确保客户端处理完业务后必定能成功发送消息。
二、确保服务端必定可以消费掉此消息。
剩下的就看咱们如何在交互上完成这两个目标。架构

2、客户端提交

客户端提交大概能够分为以下几个步骤:
一、A系统预提交消息。
二、消息服务器保存消息,可是处于未提交状态,不能被B系统消费。
三、消息服务器给予响应。
四、A系统处理本地业务。
五、A系统提交事务。 分布式

可能会存在的问题:
一、第一、二、3步其中之一出现问题,则不会执行A系统本地业务,故不会出现问题。
二、第4步若是执行失败,则直接回滚此操做。
三、第5步若是执行失败,则消息服务器不知道A系统的执行状态,这个场景下,咱们须要在A系统中开放查询接口,供消息服务器反查。若是查询到A系统的状态是已提交,则消息服务器将同步此状态,使得B系统能够正常消费。若是查询到A系统的状态是已回滚,则消息服务器将这个消息删除。 微服务

经过以上操做,咱们能够保证A系统的业务执行状态和消息的发送状态是一致的。可能有的同窗会有所疑问,上述操做有点繁琐,为什么不先执行A业务,再提交消息和事务呢?以下图:
网站

仔细思考一下,这样作是存在问题的。A业务处理成功后,消息预提交阶段可能会失败,好比网络缘由或者消息服务器自身内部缘由,致使这个消息没有持久化。正由于没有持久化,消息服务器不会进行反查,这会致使A业务处理状态和消息服务器的消息状态不一致,更别谈被B系统消费了。spa

3、服务端消费

服务端消费分为以下几个步骤:
一、B系统消费消息。
二、B系统处理本地业务。
三、消费响应,此时消息服务器能够将消息删除。 .net

在服务端消费部分,咱们要保证消费必定要成功。可能会出现如下状况:
一、B系统没法接受到消息。
二、B系统处理本地业务失败,没法给予消息服务器响应。
这两种场景下,咱们须要对消息服务器提出要求,若是再超时时间范围内,仍然获取不到B系统的消费响应,则进行超时重发,固然B系统须要保证幂等性。可是超时重发须要注意一下,由于有可能B系统一直执行失败,不能陷入无限的重发操做中。这时,咱们须要在消息服务器层对消息属性进行定义,即设置一个超时重发的次数,超过了就不在重发,避免资源浪费。消息重发次数若是达到了阈值,说明咱们的系统可能出现了问题,这种场景要可以被监控平台捕捉,以便及早的进行人工干预。设计

4、差错处理

设计再严格的系统,咱们都不能掉以轻心。理想状态下,AB系统是能够保证数据的一致性,但不排除有其余意外状况。咱们能够根据业务规则,对AB系统的数据进行监控,若是出现不一致的状况,要及早的进行人工干预。

相关文章
相关标签/搜索