基於消息中間件的分佈式事務

前言

此文來源於個人博客網站: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系統的數據進行監控,若是出現不一致的狀況,要及早的進行人工干預。

相關文章
相關標籤/搜索