摘要:如上圖所示,的實際上是已中間件的形式放在應(yīng)用層,不用依賴數(shù)據(jù)庫對協(xié)議的支持,完全剝離了分布式事務(wù)方案對數(shù)據(jù)庫在協(xié)議支持上的要求。
微信公眾號「后端進(jìn)階」,專注后端技術(shù)分享:Java、Golang、WEB框架、分布式中間件、服務(wù)治理等等。
在微服務(wù)架構(gòu)體系下,我們可以按照業(yè)務(wù)模塊分層設(shè)計,多帶帶部署,減輕了服務(wù)部署壓力,也解耦了業(yè)務(wù)的耦合,避免了應(yīng)用逐漸變成一個龐然怪物,從而可以輕松擴(kuò)展,在某些服務(wù)出現(xiàn)故障時也不會影響其它服務(wù)的正常運行。總之,微服務(wù)在業(yè)務(wù)的高速發(fā)展中帶給我們越來越多的優(yōu)勢,但是微服務(wù)并不是十全十美,因此不能盲目過度濫用,它有很多不足,而且會給系統(tǒng)帶來一定的復(fù)雜度,其中伴隨而來的分布式事務(wù)問題,是微服務(wù)架構(gòu)體系下必然需要處理的一個痛點,也是業(yè)界一直關(guān)注的一個領(lǐng)域,因此也出現(xiàn)了諸如 CAP 和 BASE 等理論。
在今年年初,阿里開源了一個分布式事務(wù)中間件,起初起名為 Fescar,后改名為 Seata,在它開源之初,我就知道它肯定要火,因為這是一個解決痛點的開源項目,Seata 一開始就是沖著對業(yè)務(wù)無侵入與高性能方向走,這正是我們對解決分布式事務(wù)問題迫切的需求。因為待過的幾家公司,用的都是微服務(wù)架構(gòu),但是在解決分布式事務(wù)的問題上都不太優(yōu)雅,所以我也在一直關(guān)注 Seata 的發(fā)展,今天就簡要說說它的一些設(shè)計上的原理,后續(xù)我將會對它的各個模塊進(jìn)行深入源碼分析,感興趣的可以持續(xù)關(guān)注我的公眾號或者博客,不要跟丟。
分布式事務(wù)解決的方案有哪些?目前分布式事務(wù)解決的方案主要有對業(yè)務(wù)無入侵和有入侵的方案,無入侵方案主要有基于數(shù)據(jù)庫 XA 協(xié)議的兩段式提交(2PC)方案,它的優(yōu)點是對業(yè)務(wù)代碼無入侵,但是它的缺點也是很明顯:必須要求數(shù)據(jù)庫對 XA 協(xié)議的支持,且由于 XA 協(xié)議自身的特點,它會造成事務(wù)資源長時間得不到釋放,鎖定周期長,而且在應(yīng)用層上面無法干預(yù),因此它性能很差,它的存在相當(dāng)于七傷拳那樣“傷人七分,損己三分”,因此在互聯(lián)網(wǎng)項目中并不是很流行這種解決方案。
為了這個彌補(bǔ)這種方案帶來性能低的問題,大佬們又想出了很多種方案來解決,但這無一例外都需要通過在應(yīng)用層做手腳,即入侵業(yè)務(wù)的方式,比如很出名的 TCC 方案,基于 TCC 也有很多成熟的框架,如 ByteTCC、tcc-transaction 等。以及基于可靠消息的最終一致性來實現(xiàn),如 RocketMQ 的事務(wù)消息。
入侵代碼的方案是基于現(xiàn)有情形“迫不得已”才推出的解決方案,實際上它們實現(xiàn)起來非常不優(yōu)雅,一個事務(wù)的調(diào)用通常伴隨而來的是對該事務(wù)接口增加一系列的反向操作,比如 TCC 三段式提交,提交邏輯必然伴隨著回滾的邏輯,這樣的代碼會使得項目非常臃腫,維護(hù)成本高。
Seata 各模塊之間的關(guān)系針對上面所說的分布式事務(wù)解決方案的痛點,那很顯然,我們理想的分布式事務(wù)解決方案肯定是性能要好而且要對業(yè)務(wù)無入侵,業(yè)務(wù)層上無需關(guān)心分布式事務(wù)機(jī)制的約束,Seata 正是往這個方向發(fā)展的,因此它非常值得期待,它將給我們的微服務(wù)架構(gòu)帶來質(zhì)的提升。
那 Seata 是怎么做到的呢?下面說說它的各個模塊之間的關(guān)系。
Seata 的設(shè)計思路是將一個分布式事務(wù)可以理解成一個全局事務(wù),下面掛了若干個分支事務(wù),而一個分支事務(wù)是一個滿足 ACID 的本地事務(wù),因此我們可以操作分布式事務(wù)像操作本地事務(wù)一樣。
Seata 內(nèi)部定義了 3個模塊來處理全局事務(wù)和分支事務(wù)的關(guān)系和處理過程,這三個組件分別是:
Transaction Coordinator (TC): 事務(wù)協(xié)調(diào)器,維護(hù)全局事務(wù)的運行狀態(tài),負(fù)責(zé)協(xié)調(diào)并驅(qū)動全局事務(wù)的提交或回滾。
Transaction Manager (TM): 控制全局事務(wù)的邊界,負(fù)責(zé)開啟一個全局事務(wù),并最終發(fā)起全局提交或全局回滾的決議。
Resource Manager (RM): 控制分支事務(wù),負(fù)責(zé)分支注冊、狀態(tài)匯報,并接收事務(wù)協(xié)調(diào)器的指令,驅(qū)動分支(本地)事務(wù)的提交和回滾。
簡要說說整個全局事務(wù)的執(zhí)行步驟:
TM 向 TC 申請開啟一個全局事務(wù),TC 創(chuàng)建全局事務(wù)后返回全局唯一的 XID,XID 會在全局事務(wù)的上下文中傳播;
RM 向 TC 注冊分支事務(wù),該分支事務(wù)歸屬于擁有相同 XID 的全局事務(wù);
TM 向 TC 發(fā)起全局提交或回滾;
TC 調(diào)度 XID 下的分支事務(wù)完成提交或者回滾。
與 XA 方案有什么不同?Seata 的事務(wù)提交方式跟 XA 協(xié)議的兩段式提交在總體上來說基本是一致的,那它們之間有什么不同呢?
我們都知道 XA 協(xié)議它依賴的是數(shù)據(jù)庫層面來保障事務(wù)的一致性,也即是說 XA 的各個分支事務(wù)是在數(shù)據(jù)庫層面上驅(qū)動的,由于 XA 的各個分支事務(wù)需要有 XA 的驅(qū)動程序,一方面會導(dǎo)致數(shù)據(jù)庫與 XA 驅(qū)動耦合,另一方面它會導(dǎo)致各個分支的事務(wù)資源鎖定周期長,這也是它沒有在互聯(lián)網(wǎng)公司流行的重要因素。
基于 XA 協(xié)議以上的問題,Seata 另辟蹊徑,既然在依賴數(shù)據(jù)庫層會導(dǎo)致這么多問題,那我就從應(yīng)用層做手腳,這還得從 Seata 的 RM 模塊說起,前面也說過 RM 的主要作用了,其實 RM 在內(nèi)部做了對數(shù)據(jù)庫操作的代理層,如下:
Seata 在數(shù)據(jù)源做了一層代理層,所以我們使用 Seata 時,我們使用的數(shù)據(jù)源實際上用的是 Seata 自帶的數(shù)據(jù)源代理 DataSourceProxy,Seata 在這層代理中加入了很多邏輯,主要是解析 SQL,把業(yè)務(wù)數(shù)據(jù)在更新前后的數(shù)據(jù)鏡像組織成回滾日志,并將 undo log 日志插入 undo_log 表中,保證每條更新數(shù)據(jù)的業(yè)務(wù) sql 都有對應(yīng)的回滾日志存在。
這樣做的好處就是,本地事務(wù)執(zhí)行完可以立即釋放本地事務(wù)鎖定的資源,然后向 TC 上報分支狀態(tài)。當(dāng) TM 決議全局提交時,就不需要同步協(xié)調(diào)處理了,TC 會異步調(diào)度各個 RM 分支事務(wù)刪除對應(yīng)的 undo log 日志即可,這個步驟非常快速地可以完成;當(dāng) TM 決議全局回滾時,RM 收到 TC 發(fā)送的回滾請求,RM 通過 XID 找到對應(yīng)的 undo log 回滾日志,然后執(zhí)行回滾日志完成回滾操作。
如上圖所示,XA 方案的 RM 是放在數(shù)據(jù)庫層的,它依賴了數(shù)據(jù)庫的 XA 驅(qū)動程序。
如上圖所示,Seata 的 RM 實際上是已中間件的形式放在應(yīng)用層,不用依賴數(shù)據(jù)庫對協(xié)議的支持,完全剝離了分布式事務(wù)方案對數(shù)據(jù)庫在協(xié)議支持上的要求。
分支事務(wù)如何提交和回滾?下面詳細(xì)說說分支事務(wù)是如何提交和回滾的:
第一階段:
分支事務(wù)利用 RM 模塊中對 JDBC 數(shù)據(jù)源代理,加入了若干流程,對業(yè)務(wù) SQL 進(jìn)行解釋,把業(yè)務(wù)數(shù)據(jù)在更新前后的數(shù)據(jù)鏡像組織成回滾日志,并生成 undo log 日志,對全局事務(wù)鎖的檢查以及分支事務(wù)的注冊等,利用本地事務(wù) ACID 特性,將業(yè)務(wù) SQL 和 undo log 寫入同一個事物中一同提交到數(shù)據(jù)庫中,保證業(yè)務(wù) SQL 必定存在相應(yīng)的回滾日志,最后對分支事務(wù)狀態(tài)向 TC 進(jìn)行上報。
第二階段:
TM決議全局提交:
當(dāng) TM 決議提交時,就不需要同步協(xié)調(diào)處理了,TC 會異步調(diào)度各個 RM 分支事務(wù)刪除對應(yīng)的 undo log 日志即可,這個步驟非常快速地可以完成。這個機(jī)制對于性能提升非常關(guān)鍵,我們知道正常的業(yè)務(wù)運行過程中,事務(wù)執(zhí)行的成功率是非常高的,因此可以直接在本地事務(wù)中提交,這步對于提升性能非常顯著。
TM決議全局回滾:
當(dāng) TM 決議回滾時,RM 收到 TC 發(fā)送的回滾請求,RM 通過 XID 找到對應(yīng)的 undo log 回滾日志,然后利用本地事務(wù) ACID 特性,執(zhí)行回滾日志完成回滾操作并刪除 undo log 日志,最后向 TC 進(jìn)行回滾結(jié)果上報。
業(yè)務(wù)對以上所有的流程都無感知,業(yè)務(wù)完全不關(guān)心全局事務(wù)的具體提交和回滾,而且最重要的一點是 Seata 將兩段式提交的同步協(xié)調(diào)分解到各個分支事務(wù)中了,分支事務(wù)與普通的本地事務(wù)無任何差異,這意味著我們使用 Seata 后,分布式事務(wù)就像使用本地事務(wù)一樣,完全將數(shù)據(jù)庫層的事務(wù)協(xié)調(diào)機(jī)制交給了中間件層 Seata 去做了,這樣雖然事務(wù)協(xié)調(diào)搬到應(yīng)用層了,但是依然可以做到對業(yè)務(wù)的零侵入,從而剝離了分布式事務(wù)方案對數(shù)據(jù)庫在協(xié)議支持上的要求,且 Seata 在分支事務(wù)完成之后直接釋放資源,極大減少了分支事務(wù)對資源的鎖定時間,完美避免了 XA 協(xié)議需要同步協(xié)調(diào)導(dǎo)致資源鎖定時間過長的問題。
其它方案的補(bǔ)充上面說的其實是 Seata 的默認(rèn)模式,也叫 AT 模式,它是類似于 XA 方案的兩段式提交方案,并且是對業(yè)務(wù)無侵入,但是這種機(jī)制依然是需要依賴數(shù)據(jù)庫本地事務(wù)的 ACID 特性,有沒有發(fā)現(xiàn),我在上面的圖中都強(qiáng)調(diào)了必須是支持 ACID 特性的關(guān)系型數(shù)據(jù)庫,那么問題就來了,非關(guān)系型或者不支持 ACID 的數(shù)據(jù)庫就無法使用 Seata 了,別慌,Seata 現(xiàn)階段為我們準(zhǔn)備了另外一種模式,叫 MT 模式,它是一種對業(yè)務(wù)有入侵的方案,提交回滾等操作需要我們自行定義,業(yè)務(wù)邏輯需要被分解為 Prepare/Commit/Rollback 3 部分,形成一個 MT 分支,加入全局事務(wù),它存在的意義是為 Seata 觸達(dá)更多的場景。
只不過,它不是 Seata “主打”的模式,它的存在僅僅作為補(bǔ)充的方案,從以上官方的發(fā)展遠(yuǎn)景就可以看出來,Seata 的目標(biāo)是始終是對業(yè)務(wù)無入侵的方案。
注:本文圖片設(shè)計參考Seata官方圖
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/75270.html
摘要:學(xué)習(xí)路線編程基礎(chǔ)語言語言基礎(chǔ)數(shù)據(jù)類型面向?qū)ο蠼涌谌萜鳟惓7盒头瓷渥⒔饬骷项惣虞d機(jī)制字節(jié)碼執(zhí)行機(jī)制 Java學(xué)習(xí)路線 Java編程基礎(chǔ) Java語言 Java語言基...
摘要:三實踐案例案例簡介分布式系統(tǒng)中,微服務(wù)基礎(chǔ)組件等,系統(tǒng)中間件,等,對常用功能配置等,進(jìn)行二次淺封裝并統(tǒng)一集成管理,以滿足日常開發(fā)中基礎(chǔ)環(huán)境搭建與臨時工具的快速實現(xiàn)。 一、背景簡介 分布式系統(tǒng)中存在很多拆分的服務(wù),在不斷迭代升級的過程中,會出現(xiàn)如下常見的棘手情況: 某個技術(shù)組件版本升級,依賴包升級導(dǎo)致部分語法或者API過期,或者組件修復(fù)緊急的問題,從而會導(dǎo)致分布式系統(tǒng)下各個服...
摘要:簡介地址版本和版本為,一直在快速迭代在之前都有可能出現(xiàn)協(xié)議不兼容盡量使用版本號一致說明目前提供的示例是針對使用的服務(wù),那的項目如何集成呢快速開始使用案例購買商品的業(yè)務(wù)邏輯。 簡介 github地址 spring-boot-starter-seata:https://github.com/itrickzhan... seata版本 server和client版本為0.4.1,Seata ...
摘要:在之后,也終于發(fā)布了最新的版本。該版本距離上一次發(fā)布,過去了整整個月下面就隨我一起看看,這個大家期待已久的版本都有哪些內(nèi)容值得我們關(guān)注。如果是用戶,同時也是阿里云這些產(chǎn)品的用戶,那么直接使用還是非常方便的。 在Nacos 1.0.0 Release之后,Spring Cloud Alibaba也終于發(fā)布了最新的版本。該版本距離上一次發(fā)布,過去了整整4個月!下面就隨我一起看看,這個大家期...
閱讀 2327·2021-09-26 10:21
閱讀 2805·2021-09-08 09:36
閱讀 3070·2019-08-30 15:56
閱讀 963·2019-08-30 12:57
閱讀 934·2019-08-26 10:39
閱讀 3565·2019-08-23 18:11
閱讀 3086·2019-08-23 17:12
閱讀 1089·2019-08-23 12:18