導讀:數據庫
本文就微服務事務一致性問題產生根源、業界經常使用方案優缺點進行了分析對比,在此基礎上提出了用友微服務事務一致性解決方案,詳細介紹了用友CC事務模型及原理,以及此方案解決的場景。編程
在傳統巨石應用架構模式下,架構特色主要是mvc模式,由controller層負責對外提供服務接口,全部功能集中在一個服務實例中,經過增減服務實例來擴展集羣的處理能力,但數據持久化集中在一個數據庫存儲,數據一致性主要依靠傳統數據庫本地事務機制保證,這種架構模式特色是簡單、快捷,方便業務規模不大,業務功能單一的場景,隨着業務增加,不管是業務規模仍是業務範圍都在快速變化,這種巨石架構模式就顯得力不從心,不易於開發協調,所以,微服務架構模式應運而生,所謂微服務通俗來講就是對服務進行垂直拆分,將一個總體服務拆分紅功能相對獨立的單元服務,各單元服務之間經過rpc進行同步或異步調用。微服務架構模式下各個服務單元各自有獨立的數據持久層,一個業務請求須要多個微服務單元共同協做,要求各服務單元要麼同時成功或同時失敗,但微服務實例分別部署在不一樣的進程或主機節點上,每一個服務實例的狀態、網絡等狀況是不可預知的,所以,如何保證一個業務請求中各單元服務數據保持一致性成爲微服務架構中一個關鍵的問題。網絡
兩階段提交架構
兩階段提交屬於剛性事務,兩階段分爲準備階段和提交階段,在準備階段,由事務協調器向各個參與者發送Prepare消息,參與者收到消息後,要麼返回失敗,要麼執行本地事務,並寫本地redo和undo日誌,可是並不commit事務,此時,本地事務資源是被鎖定狀態,其它服務或應用是不能使用此資源的。在提交階段,事務協調者在接收到全部參與者事務消息通知以後,根據全部參與者提交階段返回的狀態肯定在提交階段是回滾仍是提交事務,只要有一個參與者超時或者失敗,協調者就向全部參與者發送回滾請求,不然就向參與者發送提交請求。mvc
二階段提交的優勢框架
1)實現了事務的隔離,確保了強一致性,即本地事務未提交的數據對其它事務不可見,事務要麼都提交成功要麼都失敗異步
2)業務編程簡單,因爲事務管理是由事務協調者及本地事務資源管理器實現,開發者必需要介入太多事務相關的工做分佈式
二階段提交缺點微服務
1)同步阻塞調用,在事務執行過程當中,全部參與者同步鎖定資源以實現隔離,被鎖定的資源不能被其餘事務訪問性能
2)須要本地事務支持,即本地數據庫須要支持xa協議
3)須要事務協調者,協調者存在單點問題
4)事務會出現沒法確認的狀態。當協調者發出commit請求後,而後協調者宕機,而參與者可能只有一個已提交,其它參與者還沒有提交,此時若是惟一的參與者也宕機,整個事務狀態將沒法確認
5)主要解決的單JVM跨庫的事務一致性
TCC事務
TCC事務即Try-Confirm-cancel三個階段,是柔性事務的一種,實現的是最終一致性,適合於同步調用過程。TCC是應用層的兩階段提交,不須要事務本地數據庫對XA協議的支持。TCC事務模型有三個部分組成
·主業務服務
主業務服務爲整個業務活動的發起方,一般是服務聚合應用,好比商城系統的下單系統,下單時須要調用庫存系統減庫存,支付系統付款及積分系統給用戶積分以及購物車系統清理購物車內容。
·從業務服務
從業務服務負責提供TCC業務操做,是整個業務活動的操做方。從業務服務必須實現Try、Confirm和Cancel三個接口,供主業務服務調用。因爲Confirm和Cancel操做可能被重複調用,故要求Confirm和Cancel兩個接口必須是冪等的。
·業務活動管理器
業務活動管理器管理控制整個業務活動,包括記錄維護TCC全局事務的事務狀態和每一個從業務服務的子事務狀態,並在業務活動提交時確認全部的TCC型操做的confirm操做,在業務活動取消時調用全部TCC型操做的cancel操做。
1)Try:嘗試執行業務
完成全部業務檢查(一致性)
預留必須業務資源(準隔離性)
2)Confirm:確認執行業務
真正執行業務
不作任何業務檢查
只使用Try階段預留的業務資源
只要Try階段執行成功,須要確保Confirm必定成功,能夠不斷重試
3)Cancel:取消執行業務
釋放Try階段預留的業務資源
只要try階段失敗,必須確保Cancel最終必定成功
TCC模式優勢
1)解決了跨應用的事務問題
2)把數據庫層面的兩階段提交提到應用層來實現,不須要數據庫層面來支持XA協議,規避了數據庫的XA支持的缺陷
TCC模式缺點
1)須要從業務的角度來設計業務接口,確保業務可分解成Try、Confirm、Cancel三個階段,增長了業務編程的複雜性
2)因爲每一個應用的網絡不必定可靠,可能會屢次調用業務接口,須要業務層面考慮冪等性操做
3)因爲三個階段都是同步調用過程,所以隨着參與者增多,對主業務響應速度有影響
基於消息隊列的最終一致性
基於消息隊列的最終一致性考慮的場景是業務之間經過異步調用來實現,即做爲服務調用方發起方異步調用以後當即返回,沒必要等待被調用服務實際返回結果,這樣就能夠基於消息隊列來實現業務之間的解耦,由各業務來確保最終一致性。
基於消息隊列的最終一致性方案的優勢
1)各業務之間徹底解耦,單個業務性能不會影響總體服務
2)有助於提高服務的總體性能和吞吐量
3)實現起來簡單,只須要參與事務的各方在收到消息後確保本地事務一致性、冪等性
基於消息隊列的最終一致性方案的缺點
1)須要業務調用方來確保本地事務和發送消息的原子性,雖然像ActiveMq支持事務消息,可是事務消息對性能影響較大,能夠在本地創建消息表的方式來確保本地事務與發送消息同時成功或失敗
2)當出現不一致時,須要人工介入處理各個業務的執行狀態
用友微服務治理中的事務一致性解決方案綜合了TCC與基於消息隊列的最終一致性,CC事務模型,即Confirm 和Cancel模型。該模型將分佈式事務邊界劃以異步調用爲邊界,只要在調用鏈中加入事務的同步調用,都屬於一個全局事務,在這個全局事務中,保證事務的最終一致性,如圖:
在此圖中一個完整的調用鏈從A服務開始,在左邊方框內是rpc同步調用,而右邊也是一個rpc同步調用,兩個方框之間的服務C是經過異步調用框架EOS基於可靠消息隊列對服務E發起調用,CC事務模型將這次調用當作兩個事務處理。
CC事務模型事務狀態變化時序圖,rpc調用鏈關係爲A->B,B->C,B->D,C->E,時序圖以下:
CC事務模型過程,A同步調用B服務,事務框架在A服務內部數據庫記錄對B的調用上下文及事務記錄,事務狀態爲Confirming狀態,同時,rpc框架將事務上下文傳遞給B,B服務接收到rpc調用請求,B服務記錄事務,同時事務爲Confirming狀態,同理,B調用C,C調用E,B調用D.此時,若是B調用D異常,則B本地事務回滾,同時B服務捕捉到異常後根據B服務記錄的調用關係上下文,經過EOS框架向C和D發起異步補償方法調用,全部方法補償方法調用成功,則B事務狀態爲Cancelled,C服務補償調用成功後繼續向E服務發起異步補償調用。同時,B向A拋出異常,A捕捉異常後執行補償異步調用,同時本地事務回滾,最終AB事務狀態爲Cancelled或者Confirming狀態,C、D、E已提交事務執行補償方法後狀態爲Cancelled.最終,全部的事務狀態都會confirmed時,則事務成功,或者全部狀態都爲Cancelled時,回退成功,若是有節點處於Confirming狀態,說明整個事務發生了不一致狀態,須要人工介入處理。
CC事務模型優勢
1)沒有事務管理器的概念,每一個事務節點都是對等的
2)模型簡單,代碼侵入少,開發者只須要在業務接口上方法上使用@CCTransaction(cancel='異常時補償事務方法')標識此方法歸入事務管理,同時,補償方法上加入@CCTransCancel
3)異步消息補償機制。事務補償機制經過EOS可靠消息投遞,減小事務補償回調對業務系統性能的影響
CC事務模型缺點
1)該事務模型與自研rpc框架iris綁定,不支持其它rpc框架
2)沒有Try階段鎖定資源,一進入事務本地事務就已實際提交,不具有事務隔離能力,業務須要考慮如何實現Cancel才能符合業務實際回滾需求。