原文地址:https://mp.weixin.qq.com/s/bUtu2nTs0bybnTvk-iLt6Q
阿里妹導(dǎo)讀:分布式事務(wù)已經(jīng)成為微服務(wù)落地最大的阻礙咸灿,也是非常具有挑戰(zhàn)性的一個(gè)技術(shù)難題炼团。 為此显设,今天我們邀請(qǐng)阿里高級(jí)技術(shù)專家于皋任洞,和大家深入探討微服務(wù)架構(gòu)下侨拦,分布式事務(wù)的各種解決方案款咖,并重點(diǎn)為大家解讀阿里巴巴提出的分布式事務(wù)解決方案----GTS(Global Transaction Service)围苫。
1 微服務(wù)的發(fā)展
微服務(wù)倡導(dǎo)將復(fù)雜的單體應(yīng)用拆分為若干個(gè)功能簡(jiǎn)單退盯、松耦合的服務(wù)彼乌,這樣可以降低開(kāi)發(fā)難度、增強(qiáng)擴(kuò)展性渊迁、便于敏捷開(kāi)發(fā)慰照。當(dāng)前被越來(lái)越多的開(kāi)發(fā)者推崇,很多互聯(lián)網(wǎng)行業(yè)巨頭琉朽、開(kāi)源社區(qū)等都開(kāi)始了微服務(wù)的討論和實(shí)踐毒租。Hailo有160個(gè)不同服務(wù)構(gòu)成,NetFlix有大約600個(gè)服務(wù)箱叁。國(guó)內(nèi)方面墅垮,阿里巴巴惕医、騰訊、360噩斟、京東曹锨、58同城等很多互聯(lián)網(wǎng)公司都進(jìn)行了微服務(wù)化實(shí)踐。當(dāng)前微服務(wù)的開(kāi)發(fā)框架也非常多剃允,比較著名的有Dubbo沛简、SpringCloud、thrift 斥废、grpc等椒楣。
2 微服務(wù)落地存在的問(wèn)題
雖然微服務(wù)現(xiàn)在如火如荼,但對(duì)其實(shí)踐其實(shí)仍處于探索階段牡肉。很多中小型互聯(lián)網(wǎng)公司捧灰,鑒于經(jīng)驗(yàn)、技術(shù)實(shí)力等問(wèn)題统锤,微服務(wù)落地比較困難毛俏。如著名架構(gòu)師Chris Richardson所言,目前存在的主要困難有如下幾方面:
1)單體應(yīng)用拆分為分布式系統(tǒng)后饲窿,進(jìn)程間的通訊機(jī)制和故障處理措施變的更加復(fù)雜煌寇。
2)系統(tǒng)微服務(wù)化后,一個(gè)看似簡(jiǎn)單的功能逾雄,內(nèi)部可能需要調(diào)用多個(gè)服務(wù)并操作多個(gè)數(shù)據(jù)庫(kù)實(shí)現(xiàn)阀溶,服務(wù)調(diào)用的分布式事務(wù)問(wèn)題變的非常突出。
3)微服務(wù)數(shù)量眾多鸦泳,其測(cè)試银锻、部署、監(jiān)控等都變的更加困難做鹰。
隨著RPC框架的成熟击纬,第一個(gè)問(wèn)題已經(jīng)逐漸得到解決。例如dubbo可以支持多種通訊協(xié)議钾麸,springcloud可以非常好的支持restful調(diào)用更振。對(duì)于第三個(gè)問(wèn)題,隨著docker喂走、devops技術(shù)的發(fā)展以及各公有云paas平臺(tái)自動(dòng)化運(yùn)維工具的推出,微服務(wù)的測(cè)試谋作、部署與運(yùn)維會(huì)變得越來(lái)越容易芋肠。
而對(duì)于第二個(gè)問(wèn)題,現(xiàn)在還沒(méi)有通用方案很好的解決微服務(wù)產(chǎn)生的事務(wù)問(wèn)題遵蚜。分布式事務(wù)已經(jīng)成為微服務(wù)落地最大的阻礙帖池,也是最具挑戰(zhàn)性的一個(gè)技術(shù)難題奈惑。 為此,本文將深入和大家探討微服務(wù)架構(gòu)下睡汹,分布式事務(wù)的各種解決方案肴甸,并重點(diǎn)為大家解讀阿里巴巴提出的分布式事務(wù)解決方案----GTS。該方案中提到的GTS是全新一代解決微服務(wù)問(wèn)題的分布式事務(wù)互聯(lián)網(wǎng)中間件囚巴。
3 傳統(tǒng)分布式事務(wù)解決方案
3.1 基于XA協(xié)議的兩階段提交方案
交易中間件與數(shù)據(jù)庫(kù)通過(guò) XA 接口規(guī)范原在,使用兩階段提交來(lái)完成一個(gè)全局事務(wù), XA 規(guī)范的基礎(chǔ)是兩階段提交協(xié)議彤叉。 第一階段是表決階段庶柿,所有參與者都將本事務(wù)能否成功的信息反饋發(fā)給協(xié)調(diào)者;第二階段是執(zhí)行階段秽浇,協(xié)調(diào)者根據(jù)所有參與者的反饋浮庐,通知所有參與者,步調(diào)一致地在所有分支上提交或者回滾柬焕。
兩階段提交方案應(yīng)用非常廣泛审残,幾乎所有商業(yè)OLTP數(shù)據(jù)庫(kù)都支持XA協(xié)議。但是兩階段提交方案鎖定資源時(shí)間長(zhǎng)斑举,對(duì)性能影響很大搅轿,基本不適合解決微服務(wù)事務(wù)問(wèn)題。
3.2 TCC方案
TCC方案在電商懂昂、金融領(lǐng)域落地較多介时。TCC方案其實(shí)是兩階段提交的一種改進(jìn)。其將整個(gè)業(yè)務(wù)邏輯的每個(gè)分支顯式的分成了Try凌彬、Confirm沸柔、Cancel三個(gè)操作。Try部分完成業(yè)務(wù)的準(zhǔn)備工作铲敛,confirm部分完成業(yè)務(wù)的提交褐澎,cancel部分完成事務(wù)的回滾》ソ基本原理如下圖所示工三。
事務(wù)開(kāi)始時(shí),業(yè)務(wù)應(yīng)用會(huì)向事務(wù)協(xié)調(diào)器注冊(cè)啟動(dòng)事務(wù)先鱼。之后業(yè)務(wù)應(yīng)用會(huì)調(diào)用所有服務(wù)的try接口俭正,完成一階段準(zhǔn)備。之后事務(wù)協(xié)調(diào)器會(huì)根據(jù)try接口返回情況焙畔,決定調(diào)用confirm接口或者cancel接口掸读。如果接口調(diào)用失敗,會(huì)進(jìn)行重試。
TCC方案讓應(yīng)用自己定義數(shù)據(jù)庫(kù)操作的粒度儿惫,使得降低鎖沖突澡罚、提高吞吐量成為可能。 當(dāng)然TCC方案也有不足之處肾请,集中表現(xiàn)在以下兩個(gè)方面:
對(duì)應(yīng)用的侵入性強(qiáng)留搔。業(yè)務(wù)邏輯的每個(gè)分支都需要實(shí)現(xiàn)try、confirm铛铁、cancel三個(gè)操作隔显,應(yīng)用侵入性較強(qiáng),改造成本高避归。
實(shí)現(xiàn)難度較大荣月。需要按照網(wǎng)絡(luò)狀態(tài)、系統(tǒng)故障等不同的失敗原因?qū)崿F(xiàn)不同的回滾策略梳毙。為了滿足一致性的要求哺窄,confirm和cancel接口必須實(shí)現(xiàn)冪等。
上述原因?qū)е耇CC方案大多被研發(fā)實(shí)力較強(qiáng)账锹、有迫切需求的大公司所采用萌业。微服務(wù)倡導(dǎo)服務(wù)的輕量化、易部署奸柬,而TCC方案中很多事務(wù)的處理邏輯需要應(yīng)用自己編碼實(shí)現(xiàn)生年,復(fù)雜且開(kāi)發(fā)量大。
3.3 基于消息的最終一致性方案
消息一致性方案是通過(guò)消息中間件保證上廓奕、下游應(yīng)用數(shù)據(jù)操作的一致性抱婉。基本思路是將本地操作和發(fā)送消息放在一個(gè)事務(wù)中桌粉,保證本地操作和消息發(fā)送要么兩者都成功或者都失敗蒸绩。下游應(yīng)用向消息系統(tǒng)訂閱該消息,收到消息后執(zhí)行相應(yīng)操作铃肯。
消息方案從本質(zhì)上講是將分布式事務(wù)轉(zhuǎn)換為兩個(gè)本地事務(wù)患亿,然后依靠下游業(yè)務(wù)的重試機(jī)制達(dá)到最終一致性⊙罕疲基于消息的最終一致性方案對(duì)應(yīng)用侵入性也很高步藕,應(yīng)用需要進(jìn)行大量業(yè)務(wù)改造,成本較高挑格。
4 GTS-阿里分布式事務(wù)解決方案
GTS是一款分布式事務(wù)中間件咙冗,由阿里巴巴中間件部門研發(fā),可以為微服務(wù)架構(gòu)中的分布式事務(wù)提供一站式解決方案漂彤。
4.1 GTS的核心優(yōu)勢(shì)
-
性能超強(qiáng)
GTS通過(guò)大量創(chuàng)新雾消,解決了事務(wù)ACID特性與高性能瞬逊、高可用、低侵入不可兼得的問(wèn)題仪或。單事務(wù)分支的平均響應(yīng)時(shí)間在2ms左右,3臺(tái)服務(wù)器組成的集群可以支撐3萬(wàn)TPS以上的分布式事務(wù)請(qǐng)求士骤。
-
應(yīng)用侵入性極低
GTS對(duì)業(yè)務(wù)低侵入范删,業(yè)務(wù)代碼最少只需要添加一行注解(@TxcTransaction)聲明事務(wù)即可。業(yè)務(wù)與事務(wù)分離拷肌,將微服務(wù)從事務(wù)中解放出來(lái)到旦,微服務(wù)關(guān)注于業(yè)務(wù)本身,不再需要考慮反向接口巨缘、冪等添忘、回滾策略等復(fù)雜問(wèn)題,極大降低了微服務(wù)開(kāi)發(fā)的難度與工作量若锁。
-
完整解決方案
GTS支持多種主流的服務(wù)框架搁骑,包括EDAS,Dubbo又固,Spring Cloud等仲器。 有些情況下,應(yīng)用需要調(diào)用第三方系統(tǒng)的接口仰冠,而第三方系統(tǒng)沒(méi)有接入GTS乏冀。此時(shí)需要用到GTS的MT模式。GTS的MT模式可以等價(jià)于TCC模式洋只,用戶可以根據(jù)自身業(yè)務(wù)需求自定義每個(gè)事務(wù)階段的具體行為辆沦。MT模式提供了更多的靈活性,可能性识虚,以達(dá)到特殊場(chǎng)景下的自定義優(yōu)化及特殊功能的實(shí)現(xiàn)肢扯。
-
容錯(cuò)能力強(qiáng)
GTS解決了XA事務(wù)協(xié)調(diào)器單點(diǎn)問(wèn)題,實(shí)現(xiàn)真正的高可用舷礼,可以保證各種異常情況下的嚴(yán)格數(shù)據(jù)一致鹃彻。
4.2 GTS的應(yīng)用場(chǎng)景
GTS可應(yīng)用在涉及服務(wù)調(diào)用的多個(gè)領(lǐng)域,包括但不限于金融支付妻献、電信蛛株、電子商務(wù)、快遞物流育拨、廣告營(yíng)銷谨履、社交、即時(shí)通信熬丧、手游笋粟、視頻、物聯(lián)網(wǎng)、車聯(lián)網(wǎng)等害捕。
4.3 GTS與微服務(wù)的集成
GTS包括客戶端(GTS Client)绿淋、資源管理器(GTS RM)和事務(wù)協(xié)調(diào)器(GTS Server)三個(gè)部分。GTS Client主要用來(lái)界定事務(wù)邊界尝盼,完成事務(wù)的發(fā)起與結(jié)束吞滞。GTS RM完成事務(wù)分支的創(chuàng)建、提交盾沫、回滾等操作裁赠。GTS Server主要負(fù)責(zé)分布式事務(wù)的整體推進(jìn),事務(wù)生命周期的管理赴精。GTS和微服務(wù)集成的結(jié)構(gòu)圖如下所示佩捞,GTS Client需要和業(yè)務(wù)應(yīng)用集成部署,RM與微服務(wù)集成部署蕾哟。
4.4 GTS的輸出形式
GTS目前有三種輸出形式:公有云輸出一忱、公網(wǎng)輸出、專有云輸出谭确。
4.4.1 公有云輸出
這種輸出形式面向阿里云用戶掀潮。如果用戶的業(yè)務(wù)系統(tǒng)已經(jīng)部署到阿里云上,可以申請(qǐng)開(kāi)通公有云GTS琼富。開(kāi)通后業(yè)務(wù)應(yīng)用即可通過(guò)GTS保證服務(wù)調(diào)用的一致性仪吧。這種使用場(chǎng)景下,業(yè)務(wù)系統(tǒng)和GTS間的網(wǎng)絡(luò)環(huán)境比較理想鞠眉,達(dá)到很好性能薯鼠。
4.4.2 公網(wǎng)輸出
這種輸出形式面向于非阿里云的用戶,使用更加方便械蹋、靈活出皇,業(yè)務(wù)系統(tǒng)只要能連接互聯(lián)網(wǎng)即可享受GTS提供的云服務(wù)(與公有云輸出的差別在于客戶端部署于用戶本地,而不在云上)哗戈。
在正常網(wǎng)絡(luò)環(huán)境下郊艘,以包含兩個(gè)本地事務(wù)的全局事務(wù)為例,事務(wù)完成時(shí)間在20ms左右唯咬,50個(gè)并發(fā)就可以輕松實(shí)現(xiàn)1000TPS以上分布式事務(wù)纱注,對(duì)絕大多數(shù)業(yè)務(wù)來(lái)說(shuō)性能是足夠的。在公網(wǎng)環(huán)境胆胰,網(wǎng)絡(luò)閃斷很難完全避免狞贱,這種情況下GTS仍能保證服務(wù)調(diào)用的數(shù)據(jù)一致性。
具體使用樣例使用參見(jiàn)4.7節(jié)GTS的工程樣例蜀涨。
4.4.3 專有云輸出
這種形式主要面向于已建設(shè)了自己專有云平臺(tái)的大用戶瞎嬉,GTS可以直接部署到用戶的專有云上蝎毡,為專有云提供分布式事務(wù)服務(wù)。目前已經(jīng)有10多個(gè)特大型企業(yè)的專有云使用GTS解決分布式事務(wù)難題氧枣,性能與穩(wěn)定性經(jīng)過(guò)了用戶的嚴(yán)格檢測(cè)沐兵。
4.5 GTS的使用方式
GTS對(duì)應(yīng)用的侵入性非常低,使用也很簡(jiǎn)單便监。下面以訂單存儲(chǔ)應(yīng)用為例說(shuō)明痒筒。訂單業(yè)務(wù)應(yīng)用通過(guò)調(diào)用訂單服務(wù)和庫(kù)存服務(wù)完成訂單業(yè)務(wù),服務(wù)開(kāi)發(fā)框架為Dubbo茬贵。
4.5.1 訂單業(yè)務(wù)應(yīng)用
在業(yè)務(wù)函數(shù)外圍使用@TxcTransaction注解即可開(kāi)啟分布式事務(wù)。Dubbo應(yīng)用通過(guò)隱藏參數(shù)將GTS的事務(wù)xid傳播到服務(wù)端移袍。
4.5.2 服務(wù)提供者
更新庫(kù)存方法
4.6 GTS的應(yīng)用情況
GTS目前已經(jīng)在淘寶解藻、天貓、阿里影業(yè)葡盗、淘票票螟左、阿里媽媽、1688等阿里各業(yè)務(wù)系統(tǒng)廣泛使用觅够,經(jīng)受了16年和17年兩年雙十一海量請(qǐng)求的考驗(yàn)胶背。某線上業(yè)務(wù)系統(tǒng)最高流量已達(dá)十萬(wàn)TPS(每秒鐘10萬(wàn)筆事務(wù))。
GTS在公有云和專有云輸出后喘先,已經(jīng)有了100多個(gè)線上用戶钳吟,很多用戶通過(guò)GTS解決SpringCloud、Dubbo窘拯、Edas等服務(wù)框架的分布式事務(wù)問(wèn)題红且。業(yè)務(wù)領(lǐng)域涉及電力、物流涤姊、ETC暇番、煙草、金融思喊、零售壁酬、電商、共享出行等十幾個(gè)行業(yè)恨课,得到用戶的一致認(rèn)可舆乔。
上圖是GTS與SpringCloud集成,應(yīng)用于某共享出行系統(tǒng)剂公。業(yè)務(wù)共享出行場(chǎng)景下蜕煌,通過(guò)GTS支撐物聯(lián)網(wǎng)系統(tǒng)、訂單系統(tǒng)诬留、支付系統(tǒng)斜纪、運(yùn)維系統(tǒng)贫母、分析系統(tǒng)等系各統(tǒng)應(yīng)用的數(shù)據(jù)一致性,保證海量訂單和數(shù)千萬(wàn)流水的交易盒刚。
4.7 GTS的工程樣例
GTS的公有云樣例可參考阿里云網(wǎng)站腺劣。在公網(wǎng)環(huán)境下提供sample-txc-simple和sample-txc-dubbo兩個(gè)樣例工程。
4.7.1.1 樣例業(yè)務(wù)邏輯
該樣例是GTS的入門sample因块,案例的業(yè)務(wù)邏輯是從A賬戶轉(zhuǎn)賬給B賬戶橘原,其中A和B分別位于兩個(gè)MySQL數(shù)據(jù)庫(kù)中,使用GTS事務(wù)保證A和B賬戶錢的總數(shù)始終不變涡上。
4.7.1.2 樣例搭建方法
- 準(zhǔn)備數(shù)據(jù)庫(kù)環(huán)境
安裝MySQL趾断,創(chuàng)建兩個(gè)數(shù)據(jù)庫(kù)db1和db2。在db1和db2中分別創(chuàng)建txc_undo_log表(SQL腳本見(jiàn)4.7.3)吩愧。在db1庫(kù)中創(chuàng)建user_money_a表芋酌,在db2庫(kù)中創(chuàng)建user_money_b表。
- 下載樣例
將sample-txc-simple文件下載到本地雁佳,樣例中已經(jīng)包含了GTS的SDK脐帝。
- 修改配置
打開(kāi)sample-txc-simple/src/main/resources目錄下的txc-client-context.xml,將數(shù)據(jù)源的url糖权、username堵腹、password修改為實(shí)際值。
- 運(yùn)行樣例
在sample-txc-simple目錄下執(zhí)行build.sh編譯本工程星澳。編譯完成后執(zhí)行run.sh疚顷。
4.7.2 sample-txc-dubbo 樣例
4.7.2.1 樣例業(yè)務(wù)邏輯
本案例模擬了用戶下訂單、減庫(kù)存的業(yè)務(wù)邏輯禁偎〉春客戶端(Client)通過(guò)調(diào)用訂單服務(wù)(OrderService)創(chuàng)建訂單,之后通過(guò)調(diào)用庫(kù)存服務(wù)(StockService)扣庫(kù)存届垫。其中訂單服務(wù)讀寫訂單數(shù)據(jù)庫(kù)释液,庫(kù)存服務(wù)讀寫庫(kù)存數(shù)據(jù)庫(kù)。由 GTS 保證跨服務(wù)事務(wù)的一致性装处。
4.7.2.2 樣例搭建方法
- 準(zhǔn)備數(shù)據(jù)庫(kù)環(huán)境
安裝MySQL误债,創(chuàng)建兩個(gè)數(shù)據(jù)庫(kù)db1和db2。在db1和db2中分別創(chuàng)建txc_undo_log表妄迁。在db1庫(kù)中創(chuàng)建orders表寝蹈,在db2庫(kù)中創(chuàng)建stock表。
- 下載樣例
將樣例文件sample-txc-dubbo下載到本地機(jī)器登淘,樣例中已經(jīng)包含了GTS的SDK箫老。
- 修改配置
打開(kāi)sample-txc-dubbo/src/main/resources目錄,將dubbo-order-service.xml黔州、dubbo-stock-service.xml兩個(gè)文件中數(shù)據(jù)源的url耍鬓、username阔籽、password修改為實(shí)際值。
- 運(yùn)行樣例
a. 編譯程序
在工程根目錄執(zhí)行 build.sh 命令牲蜀,編譯工程笆制。編譯后會(huì)在 sample-txc-dubbo/client/bin 目錄下生成 order_run.sh、stock_run.sh涣达、client_run.sh 三個(gè)運(yùn)行腳本對(duì)應(yīng)訂單服務(wù)在辆、庫(kù)存服務(wù)以及客戶端。
b. 運(yùn)行程序
在根目錄執(zhí)行run.sh度苔,該腳本會(huì)依次啟動(dòng)order_run.sh(訂單服務(wù))匆篓、stock_run.sh(庫(kù)存服務(wù))和client_run.sh(客戶端程序)。
4.7.2.3 其他說(shuō)明
樣例使用Multicast注冊(cè)中心的聲明方式寇窑。如果本機(jī)使用無(wú)線網(wǎng)絡(luò)鸦概,dubbo服務(wù)在綁定地址時(shí)有可能獲取ipv6地址,可以通過(guò)jvm啟動(dòng)參數(shù)禁用疗认。 方法是配置jvm啟動(dòng)參數(shù) -Djava.net.preferIPv4Stack=true。
4.7.3 SQL
4.7.3.1 建表 txc_undo_log
CREATE TABLE txc_undo_log (
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
gmt_create datetime NOT NULL COMMENT '創(chuàng)建時(shí)間',
gmt_modified datetime NOT NULL COMMENT '修改時(shí)間',
xid varchar(100) NOT NULL COMMENT '全局事務(wù)ID',
branch_id bigint(20) NOT NULL COMMENT '分支事務(wù)ID',
rollback_info longblob NOT NULL COMMENT 'LOG',
status int(11) NOT NULL COMMENT '狀態(tài)',
server varchar(32) NOT NULL COMMENT '分支所在DB IP',
PRIMARY KEY (id),
KEY unionkey (xid,branch_id)
) ENGINE=InnoDB AUTO_INCREMENT=211225994 DEFAULT CHARSET=utf8 COMMENT='事務(wù)日志表';
4.7.3.2 建表 user_money_a
CREATE TABLE user_money_a (
id int(11) NOT NULL AUTO_INCREMENT,
money int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
4.7.3.3 建表 user_money_b
CREATE TABLE user_money_b (
id int(11) NOT NULL AUTO_INCREMENT,
money int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
4.7.3.4 建表 orders
CREATE TABLE orders (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id varchar(255) NOT NULL,
product_id int(11) NOT NULL,
number int(11) NOT NULL,
gmt_create timestamp NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=351 DEFAULT CHARSET=utf8
4.7.3.5 建表 stock
CREATE TABLE stock (
product_id int(11) NOT NULL,
price float NOT NULL,
amount int(11) NOT NULL,
PRIMARY KEY (product_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
5 總結(jié)
GTS已經(jīng)在阿里內(nèi)部廣泛使用伏钠,經(jīng)過(guò)了雙十一流量高峰的考驗(yàn)横漏。內(nèi)部成熟后,在專有云和公有云服務(wù)了很多用戶熟掂,很多用戶一天事務(wù)量在千萬(wàn)/億級(jí)別缎浇,解決了業(yè)務(wù)服務(wù)化改造后的分布式事務(wù)棘手技術(shù)難題。
我們相信赴肚,作為既滿足事務(wù)ACID特性素跺,又具備高性能、高可用誉券、業(yè)務(wù)侵入性低的分布式事務(wù)中間件指厌,未來(lái)GTS能幫助更多的開(kāi)發(fā)者,推動(dòng)行業(yè)持續(xù)發(fā)展踊跟。