SpringCloud(四) 微服务架构-事务一致性
分布式事務指事務的操作位于不同的節點上,需要保證事務的 AICD 特性。目前比較常用的分布式事務解決方案包括強一致性的兩階段提交協議、三階段提交協議以及最終一致性的可靠事件模式、補償模式、阿里的TCC模式。
事務是指由一組操作組成的一個工作單元,這個工作單元具有原子性(atomicity)、一致性(consistency)、隔離性(isolation)和持久性(durability)。 原子性:執行單元中的操作要么全部執行成功,要么全部失敗。如果有一部分成功一部分失敗那么成功的操作要全部回滾到執行前的狀態。 一致性:執行一次事務會使用數據從一個正確的狀態轉換到另一個正確的狀態,執行前后數據都是完整的。
隔離性:在該事務執行的過程中,任何數據的改變只存在于該事務之中,對外界沒有影響,事務與事務之間是完全的隔離的。只有事務提交后其它事務才可以查詢到最新的數據。 持久性:事務完成后對數據的改變會永久性的存儲起來,即使發生斷電宕機數據依然在。
強一致性
兩階段提交協議
在分布式系統中,為了解決多個節點之間的協調問題,就需要引入一個協調者負責控制所有節點的操作結果,要么全部成功,要么全部失敗。其中,XA協議是一個分布式事務協議,它有兩個角色:事務管理者和資源管理者。我們可用把事務管理者理解為協調者,資源管理者理解為參與者。XA協議通過二階段提交協議保證強一致性:
第一階段準備:事務管理者向資源管理者發起準備指令,詢問資源管理者預提交是否成功;資源管理者執行操作,并不提交,最后給出自己的響應結果
第二階段提交:如果全部資源管理者都回復預提交成功,事務管理者則發起正式提交命令;如果其中一個資源管理者回復預提交失敗,事務管理者則發起全部回滾命令
二階段提交協議的缺點
同步阻塞問題:執行過程中,所有參與節點都是事務阻塞型的。當參與者占有公共資源時,其他第三方節點訪問公共資源不得不處于阻塞狀態。
單點故障:由于協調者的重要性,一旦協調者發生故障。參與者會一直阻塞下去。尤其在第二階段,協調者發生故障,那么所有的參與者還都處于鎖定事務資源的狀態中,而無法繼續完成事務操作。(如果是協調者掛掉,可以重新選舉一個協調者,但是無法解決因為協調者宕機導致的參與者處于阻塞狀態的問題)
數據不一致:在二階段提交的階段二中,當協調者向參與者發送commit請求之后,發生了局部網絡異常或者在發送commit請求過程中協調者發生了故障,這回導致只有一部分參與者接受到了commit請求。而在這部分參與者接到commit請求之后就會執行commit操作。但是其他部分未接到commit請求的機器則無法執行事務提交。于是整個分布式系統便出現了數據部一致性的現象。
三階段提交協議
三階段提交協議與二階段的不同之處在于引入了超時機制來解決同步阻塞問題,此外加入預備階段,盡可能最早發現無法執行的資源管理者并終止事務。
最終一致性
TCC模式
TCC模式將一個任務拆分為3個操作:Try、Confirm和Cancel。在TCC模式中,主業務服務負責發起流程,而從業務服務提供TCC模式的Try、Confirm和Cancel三個操作,還有一個事務管理器的角色負責控制事務的一致性。事實上,TCC模式也是一種二階段提交。
用戶接入TCC,最重要的是考慮如何將自己的業務模型拆成兩階段來實現。
例如:賬戶業務服務,將業務劃分為資源(余額)檢查與預留階段 與 執行扣款或回滾階段。
Try 方法作為一階段準備方法(做資源的檢查和預留)
在扣錢場景下,Try 要做的事情是就是檢查賬戶余額是否充足,預留轉賬資金,預留的方式就是凍結 A 賬戶的 轉賬資金。
Try 方法執行之后,賬號 A 余額雖然還是 100,但是**其中 10 元已經被凍結了,不能被其他事務使用**。
二階段 Confirm 方法(執行真正的扣錢操作)
Confirm 會使用 Try 階段凍結的資金,執行賬號扣款。Confirm 方法執行之后,賬號 A 在一階段中凍結的 10 元已經被扣除,賬號 A 余額變成 70 元 。
如果二階段是回滾的話,就需要在 Cancel 方法內釋放一階段 Try 凍結的 10 元,使賬號 A 的回到初始狀態,100 元全部可用
需要注意的是,第二階段 confirm 或 cancel 操作本身也是滿足最終一致性的過程,在調用 confirm 或 cancel 的時候也可能因為某種原因(比如網絡)導致調用失敗,所以需要活動管理支持重試的能力,同時這也就要求 confirm 和 cancel 操作具有冪等性(所謂冪等,就是任意多次執行所產生的影響均與一次執行的影響相同)。如果業務服務向 TCC 服務框架提交confirm/cancel 失敗,不會導致不一致,因為服務最后都會超時而取消。TCC的實現框架有很多成熟的開源項目,比如tcc-transaction。它通過@Compensable切面進行攔截,可以透明化對參與者confirm/cancel方法的調用,從而實現TCC模式
補償模式
除了重試機制,還可以在每次更新時進行修復。定時校對也是一種重要的解決手段。業內比較常用的有單機場景下的Quartz以及分布式場景下的XXL-JOB等。
可靠事件模式
可靠事件模式是指通過引入可靠的消息隊列,只要保證當前的可靠事件投遞并且消息隊列確保事件傳遞至少一次,那么訂閱這個事件的消費者保證事件能夠在自己的業務內被消費即可。但是在網絡通信過程中,上下游可能因為各種原因而導致消息丟失。因此,需要通過“正反向消息機制”確保消息隊列實現可靠的事件傳遞,并且使用補償機制盡可能在一定時間內將未完成的消息重新投遞。
一般做法,是主業務服務將要發送的消息持久化到本地數據庫中,設置標志狀態為“待發送”;然后把消息發送給消息隊列,消息隊列收到消息后,也把消息持久化到其存儲服務中,但并不是立即向從業務服務(生產者)投遞消息,而是先向主業務服務(生產者)返回消息隊列的響應結果,然后主業務服務判斷響應結果執行之后的業務處理。如果響應失敗,則放棄之后的業務處理,設置本地的持久化消息標志狀態為“結束”狀態。否則,執行后續的業務處理,設置本地的持久化消息標志狀態為“已發送"狀態。
Apache RockerMQ
Apache RockerMQ是阿里開源的分布式消息中間件,4.3版本正式支持分布式事務消息。RockerMQ事務消息中間件解決了生產者端的消息發送與本地事務執行的原子性問題。 換句話說,本地事務執行不成功,則不會進行MQ消息推送。
MQ消息、DB操作一致性方案:
1)發送消息到MQ服務器,此時消息狀態為SEND_OK。此消息為consumer不可見。
2)執行DB操作;DB執行成功Commit DB操作,DB執行失敗Rollback DB操作。
3)如果DB執行成功,回復MQ服務器,將狀態為COMMIT_MESSAGE;如果DB執行失敗,回復MQ服務器,將狀態改為ROLLBACK_MESSAGE。注意此過程有可能失敗。
4)MQ內部提供一個名為“事務狀態服務”的服務,此服務會檢查事務消息的狀態,如果發現消息未COMMIT,則通過Producer啟動時注冊的TransactionCheckListener來回調業務系統,業務系統在checkLocalTransactionState方法中檢查DB事務狀態,如果成功,則回復COMMIT_MESSAGE,否則回復ROLLBACK_MESSAGE
總結
以上是生活随笔為你收集整理的SpringCloud(四) 微服务架构-事务一致性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 运用runtime与AOP实现oc中的k
- 下一篇: 列出每一个部门中年纪最大的员工姓名,部门