从“被动挖光缆”到“主动剪网线”,蚂蚁金服异地多活的微服务体系
螞蟻金服(當(dāng)時(shí)還是支付寶)從 2013 年起就運(yùn)行在單元化架構(gòu)上,除了具備異地容災(zāi)能力外,還能做到異地多活,可隨時(shí)在多城市、多數(shù)據(jù)中心調(diào)配流量。基于單元流量調(diào)配機(jī)制,可實(shí)現(xiàn)大規(guī)模集群的藍(lán)綠發(fā)布、灰度仿真環(huán)境,為充分驗(yàn)證業(yè)務(wù)正確性、降低故障提供了基礎(chǔ)條件。相應(yīng)地,微服務(wù)體系也必須具備單元內(nèi)收斂、單元間可控路由等能力,來(lái)支撐單元化技術(shù)架構(gòu)的落地。本文根據(jù)玄霄 2018 年上海 QCon 演講內(nèi)容整理。
“異地多活”是互聯(lián)網(wǎng)系統(tǒng)的一種高可用部署架構(gòu),而“單元化”正是實(shí)現(xiàn)異地多活的一個(gè)解題思路。
說(shuō)起這個(gè)話(huà)題,不得不提兩個(gè)事件:一件是三年多前的往事,另一件就發(fā)生今年的杭州云棲大會(huì)上。
從“挖光纜”到“剪網(wǎng)線(xiàn)”
2015年5月27日,因市政施工,支付寶杭州某數(shù)據(jù)中心的光纜被挖斷,造成對(duì)部分用戶(hù)服務(wù)不可用,時(shí)間長(zhǎng)達(dá)數(shù)小時(shí)。其實(shí)支付寶的單元化架構(gòu)容災(zāi)很早就開(kāi)始啟動(dòng)了,2015年也基本上成型了。當(dāng)時(shí)由于事發(fā)突然,還是碰到很多實(shí)際問(wèn)題,花費(fèi)了數(shù)小時(shí)的時(shí)間,才在確保用戶(hù)數(shù)據(jù)完全正確的前提下,完成切換、恢復(fù)服務(wù)。雖然數(shù)據(jù)沒(méi)有出錯(cuò),但對(duì)于這樣體量的公司來(lái)說(shuō),服務(wù)不可用的社會(huì)輿論影響也是非常大的。
527這個(gè)數(shù)字,成為螞蟻金服全體技術(shù)人心中懸著那顆苦膽。我們甚至把技術(shù)部門(mén)所在辦公樓的一個(gè)會(huì)議室命名為527,把每年的5月27日定為技術(shù)日,來(lái)時(shí)刻警醒自己敬畏技術(shù),不斷打磨技術(shù)。
經(jīng)過(guò)幾年的臥薪嘗膽,時(shí)間來(lái)到2018年9月。云棲大會(huì)上,螞蟻金服發(fā)布了“三地五中心金融級(jí)高可用方案”。現(xiàn)場(chǎng)部署了一個(gè)模擬轉(zhuǎn)賬系統(tǒng),在場(chǎng)觀眾通過(guò)小程序互相不斷轉(zhuǎn)賬。服務(wù)端分布在三個(gè)城市的五個(gè)數(shù)據(jù)中心,為了感受更直觀,把杭州其中一個(gè)數(shù)據(jù)中心機(jī)柜設(shè)置在了會(huì)場(chǎng)。工作人員當(dāng)場(chǎng)把杭州兩個(gè)數(shù)據(jù)中心的網(wǎng)線(xiàn)剪斷,來(lái)模擬杭州的城市級(jí)災(zāi)難。
網(wǎng)線(xiàn)剪斷之后,部分用戶(hù)服務(wù)不可用。經(jīng)過(guò)26秒,容災(zāi)切換完成,所有受影響的用戶(hù)全部恢復(fù)正常。這個(gè)Demo當(dāng)然只是實(shí)際生產(chǎn)系統(tǒng)的一個(gè)簡(jiǎn)化模型,但是其背后的技術(shù)是一致的。這幾年來(lái),其實(shí)每隔幾周我們就會(huì)在生產(chǎn)環(huán)境做一次真實(shí)的數(shù)據(jù)中心斷網(wǎng)演習(xí),來(lái)不斷打磨系統(tǒng)容災(zāi)能力。
從大屏幕上可以看到,容災(zāi)切換包含了“數(shù)據(jù)庫(kù)切換”“緩存容災(zāi)切換”“多活規(guī)則切換”“中間件切換”“負(fù)載均衡切換”“域名解析切換”等多個(gè)環(huán)節(jié)。異地多活架構(gòu)是一個(gè)復(fù)雜的系統(tǒng)工程,其包含的技術(shù)內(nèi)涵非常豐富,單場(chǎng)分享實(shí)難面面俱到。本場(chǎng)是微服務(wù)話(huà)題專(zhuān)場(chǎng),我們也將以應(yīng)用層的微服務(wù)體系作為切入點(diǎn),一窺異地多活單元化架構(gòu)的真面目。
去單點(diǎn)之路
任何一個(gè)互聯(lián)網(wǎng)系統(tǒng)發(fā)展到一定規(guī)模時(shí),都會(huì)不可避免地觸及到單點(diǎn)瓶頸。“單點(diǎn)”在系統(tǒng)的不同發(fā)展階段有不同的表現(xiàn)形式。提高系統(tǒng)伸縮能力和高可用能力的過(guò)程,就是不斷與各種層面的單點(diǎn)斗爭(zhēng)的過(guò)程。
我們不妨以一個(gè)生活中最熟悉的場(chǎng)景作為貫穿始終的例子,來(lái)推演系統(tǒng)架構(gòu)從簡(jiǎn)單到復(fù)雜,所遇到的問(wèn)題。
上圖展示的是用支付寶買(mǎi)早餐的情景,當(dāng)然角色是虛構(gòu)的。
最早支付寶只是從淘寶剝離的一個(gè)小工具系統(tǒng),處于單體應(yīng)用時(shí)代。這個(gè)時(shí)候移動(dòng)支付當(dāng)然還沒(méi)出現(xiàn),我們的例子僅用于幫助分析問(wèn)題,請(qǐng)忽略這個(gè)穿幫漏洞。
假設(shè)圖中的場(chǎng)景發(fā)生在北京,而支付寶系統(tǒng)是部署在杭州的機(jī)房。在小王按下“支付”按鈕的一瞬間,會(huì)發(fā)生什么事情呢?
支付請(qǐng)求要從客戶(hù)端發(fā)送到服務(wù)端,服務(wù)端最終再把結(jié)果返回客戶(hù)端,必然會(huì)有一次異地網(wǎng)絡(luò)往返,耗時(shí)大約在數(shù)十毫秒的數(shù)量級(jí),我們用紅色線(xiàn)表示。應(yīng)用進(jìn)程內(nèi)部會(huì)發(fā)生很多次業(yè)務(wù)邏輯運(yùn)算,用綠色圈表示,不涉及網(wǎng)絡(luò)開(kāi)銷(xiāo),耗時(shí)忽略不計(jì)。應(yīng)用會(huì)訪(fǎng)問(wèn)多次數(shù)據(jù)庫(kù),由于都在部署在同一個(gè)機(jī)房?jī)?nèi),每次耗時(shí)按一毫秒以下,一筆支付請(qǐng)求按10次數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)算(對(duì)于支付系統(tǒng)來(lái)說(shuō)并不算多,一筆業(yè)務(wù)可能涉及到各種數(shù)據(jù)校驗(yàn)、數(shù)據(jù)修改)。耗時(shí)大頭在無(wú)可避免的用戶(hù)到機(jī)房物理距離上,系統(tǒng)內(nèi)部處理耗時(shí)很小。
到了服務(wù)化時(shí)代,一個(gè)好的RPC框架追求的是讓遠(yuǎn)程服務(wù)調(diào)用像調(diào)本地方法一樣簡(jiǎn)單。隨著服務(wù)的拆分、業(yè)務(wù)的發(fā)展,原本進(jìn)程內(nèi)部的調(diào)用變成了網(wǎng)絡(luò)調(diào)用。由于應(yīng)用都部署在同一個(gè)機(jī)房?jī)?nèi),業(yè)務(wù)整體網(wǎng)絡(luò)耗時(shí)仍然在可接受范圍內(nèi)。開(kāi)發(fā)人員一般也不會(huì)特別在意這個(gè)問(wèn)題,RPC服務(wù)被當(dāng)成幾乎無(wú)開(kāi)銷(xiāo)成本地使用,應(yīng)用的數(shù)量也在逐漸膨脹。
服務(wù)化解決了應(yīng)用層的瓶頸,緊接著數(shù)據(jù)庫(kù)就成為制約系統(tǒng)擴(kuò)展的瓶頸。雖然我們本次重點(diǎn)討論的是服務(wù)層,但要講單元化,數(shù)據(jù)存儲(chǔ)是無(wú)論如何繞不開(kāi)的話(huà)題。這里先插播一下分庫(kù)分表的介紹,作為一個(gè)鋪墊。
通過(guò)引入數(shù)據(jù)訪(fǎng)問(wèn)中間件,可以實(shí)現(xiàn)對(duì)應(yīng)用透明的分庫(kù)分表。一個(gè)比較好的實(shí)踐是:邏輯拆分先一步到位,物理拆分慢慢進(jìn)行。以賬戶(hù)表為例,將用戶(hù)ID的末兩位作為分片維度,可以在邏輯上將數(shù)據(jù)分成100份,一次性拆到100個(gè)分表中。這100個(gè)分表可以先位于同一個(gè)物理庫(kù)中,隨著系統(tǒng)的發(fā)展,逐步拆成2個(gè)、5個(gè)、10個(gè),乃至100個(gè)物理庫(kù)。數(shù)據(jù)訪(fǎng)問(wèn)中間件會(huì)屏蔽表與庫(kù)的映射關(guān)系,應(yīng)用層不必感知。
解決了應(yīng)用層和數(shù)據(jù)庫(kù)層單點(diǎn)后,物理機(jī)房又成為制約系統(tǒng)伸縮能力和高可用能力的最大單點(diǎn)。
要突破單機(jī)房的容量限制,最直觀的解決辦法就是再建新的機(jī)房,機(jī)房之間通過(guò)專(zhuān)線(xiàn)連成同一個(gè)內(nèi)部網(wǎng)絡(luò)。應(yīng)用可以部署一部分節(jié)點(diǎn)到第二個(gè)機(jī)房,數(shù)據(jù)庫(kù)也可以將主備庫(kù)交叉部署到不同的機(jī)房。
這一階段,只是解決了機(jī)房容量不足的問(wèn)題,兩個(gè)機(jī)房邏輯上仍是一個(gè)整體。日常會(huì)存在兩部分跨機(jī)房調(diào)用:
服務(wù)層邏輯上是無(wú)差別的應(yīng)用節(jié)點(diǎn),每一次RPC調(diào)用都有一半的概率跨機(jī)房;
每個(gè)特定的數(shù)據(jù)庫(kù)主庫(kù)只能位于一個(gè)機(jī)房,所以宏觀上也一定有一半的數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)是跨機(jī)房的。
同城跨機(jī)房專(zhuān)線(xiàn)訪(fǎng)問(wèn)的耗時(shí)在數(shù)毫秒級(jí),圖中用黃色線(xiàn)表示。隨著微服務(wù)化演進(jìn)如火如荼,這部分耗時(shí)積少成多也很可觀。
改進(jìn)后的同城多機(jī)房架構(gòu),依靠不同服務(wù)注冊(cè)中心,將應(yīng)用層邏輯隔離開(kāi)。只要一筆請(qǐng)求進(jìn)入一個(gè)機(jī)房,應(yīng)用層就一定會(huì)在一個(gè)機(jī)房?jī)?nèi)處理完。當(dāng)然,由于數(shù)據(jù)庫(kù)主庫(kù)只在其中一邊,所以這個(gè)架構(gòu)仍然不解決一半數(shù)據(jù)訪(fǎng)問(wèn)跨機(jī)房的問(wèn)題。
這個(gè)架構(gòu)下,只要在入口處調(diào)節(jié)進(jìn)入兩個(gè)機(jī)房的請(qǐng)求比例,就可以精確控制兩個(gè)機(jī)房的負(fù)載比例。基于這個(gè)能力,可以實(shí)現(xiàn)全站藍(lán)綠發(fā)布。
“兩地三中心”是一種在金融系統(tǒng)中廣泛應(yīng)用的跨數(shù)據(jù)中心擴(kuò)展與跨地區(qū)容災(zāi)部署模式,但也存在一些問(wèn)題。異地災(zāi)備機(jī)房距離數(shù)據(jù)庫(kù)主節(jié)點(diǎn)距離過(guò)遠(yuǎn)、訪(fǎng)問(wèn)耗時(shí)過(guò)長(zhǎng),異地備節(jié)點(diǎn)數(shù)據(jù)又不是強(qiáng)一致的,所以無(wú)法直接提供在線(xiàn)服務(wù)。
在擴(kuò)展能力上,由于跨地區(qū)的備份中心不承載核心業(yè)務(wù),不能解決核心業(yè)務(wù)跨地區(qū)擴(kuò)展的問(wèn)題;在成本上,災(zāi)備系統(tǒng)僅在容災(zāi)時(shí)使用,資源利用率低,成本較高;在容災(zāi)能力上,由于災(zāi)備系統(tǒng)冷備等待,容災(zāi)時(shí)可用性低,切換風(fēng)險(xiǎn)較大。
小結(jié)一下前述幾種架構(gòu)的特點(diǎn)。直到這時(shí),微服務(wù)體系本身的變化并不大,無(wú)非是部署幾套、如何隔離的問(wèn)題,每套微服務(wù)內(nèi)部仍然是簡(jiǎn)單的架構(gòu)。
螞蟻金服單元化實(shí)踐
螞蟻金服發(fā)展單元化架構(gòu)的原始驅(qū)動(dòng)力,可以概括為兩句話(huà):
異地多活容災(zāi)需求帶來(lái)的數(shù)據(jù)訪(fǎng)問(wèn)耗時(shí)問(wèn)題,量變引起質(zhì)變;
數(shù)據(jù)庫(kù)連接數(shù)瓶頸制約了整體水平擴(kuò)展能力,危急存亡之秋。
第一條容易理解,正是前面討論的問(wèn)題,傳統(tǒng)的兩地三中心架構(gòu)在解決地區(qū)級(jí)單點(diǎn)問(wèn)題上效果并不理想,需要有其他思路。但這畢竟也不是很急的事情,真正把單元化之路提到生死攸關(guān)的重要性的,是第二條。
到2013年,支付寶核心數(shù)據(jù)庫(kù)都已經(jīng)完成了水平拆分,容量綽綽有余,應(yīng)用層無(wú)狀態(tài),也可以隨意水平擴(kuò)展。但是按照當(dāng)年雙十一的業(yè)務(wù)指標(biāo)做技術(shù)規(guī)劃的時(shí)候,卻碰到了一個(gè)棘手的問(wèn)題:Oracle數(shù)據(jù)庫(kù)的連接不夠用了。
雖然數(shù)據(jù)庫(kù)是按用戶(hù)維度水平拆分的,但是應(yīng)用層流量是完全隨機(jī)的。以圖中的簡(jiǎn)化業(yè)務(wù)鏈路為例,任意一個(gè)核心應(yīng)用節(jié)點(diǎn)C可能訪(fǎng)問(wèn)任意一個(gè)數(shù)據(jù)庫(kù)節(jié)點(diǎn)D,都需要占用數(shù)據(jù)庫(kù)連接。連接是數(shù)據(jù)庫(kù)非常寶貴的資源,是有上限的。當(dāng)時(shí)的支付寶,面臨的問(wèn)題是不能再對(duì)應(yīng)用集群擴(kuò)容,因?yàn)槊吭黾右慌_(tái)機(jī)器,就需要在每個(gè)數(shù)據(jù)分庫(kù)上新增若干連接,而此時(shí)幾個(gè)核心數(shù)據(jù)庫(kù)的連接數(shù)已經(jīng)到達(dá)上限。應(yīng)用不能擴(kuò)容,意味著支付寶系統(tǒng)的容量定格了,不能再有任何業(yè)務(wù)量增長(zhǎng)。別說(shuō)大促,可能再過(guò)一段時(shí)間連日常業(yè)務(wù)也支撐不了了。
單元化架構(gòu)基于這樣一種設(shè)想:如果應(yīng)用層也能按照數(shù)據(jù)層相同的拆片維度,把整個(gè)請(qǐng)求鏈路收斂在一組服務(wù)器中,從應(yīng)用層到數(shù)據(jù)層就可以組成一個(gè)封閉的單元。數(shù)據(jù)庫(kù)只需要承載本單元的應(yīng)用節(jié)點(diǎn)的請(qǐng)求,大大節(jié)省了連接數(shù)。“單元”可以作為一個(gè)相對(duì)獨(dú)立整體來(lái)挪動(dòng),甚至可以把部分單元部署到異地去。
單元化有幾個(gè)重要的設(shè)計(jì)原則:
核心業(yè)務(wù)必須是可分片的
必須保證核心業(yè)務(wù)的分片是均衡的,比如支付寶用用戶(hù)ID作分片維度
核心業(yè)務(wù)要盡量自包含,調(diào)用要盡量封閉
整個(gè)系統(tǒng)都要面向邏輯分區(qū)設(shè)計(jì),而不是物理部署
在實(shí)踐上,我們推薦先從邏輯上切分若干均等的單元,再根據(jù)實(shí)際物理?xiàng)l件,把單元分布到物理數(shù)據(jù)中心。單元均等的好處是更容易做容量規(guī)劃,可以根據(jù)一個(gè)單元的壓測(cè)結(jié)果方便換算成整站容量。
我們把單元叫做Regional Zone。例如,數(shù)據(jù)按100份分片,邏輯上分為5個(gè)Regional Zone,每個(gè)承載20份數(shù)據(jù)分片的業(yè)務(wù)。初期可能是部署成兩地三中心(允許多個(gè)單元位于同一個(gè)數(shù)據(jù)中心)。隨著架構(gòu)的發(fā)展,再整單元搬遷,演化成三地五中心,應(yīng)用層無(wú)需感知物理層面的變化。
回到前面買(mǎi)早餐的例子,小王的ID是12345666,分片號(hào)是66,應(yīng)該屬于Regional Zone 04;而張大媽ID是54321233,分片號(hào)33,應(yīng)該屬于Regional Zone 02。
應(yīng)用層會(huì)自動(dòng)識(shí)別業(yè)務(wù)參數(shù)上的分片位,將請(qǐng)求發(fā)到正確的單元。業(yè)務(wù)設(shè)計(jì)上,我們會(huì)保證流水號(hào)的分片位跟付款用戶(hù)的分片位保持一致,所以絕大部分微服務(wù)調(diào)用都會(huì)收斂在Regional Zone 04內(nèi)部。
但是轉(zhuǎn)賬操作一定會(huì)涉及到兩個(gè)賬戶(hù),很可能位于不同的單元。張大媽的賬號(hào)就剛好位于另一個(gè)城市的Regional Zone 02。當(dāng)支付系統(tǒng)調(diào)用賬務(wù)系統(tǒng)給張大媽的賬號(hào)加錢(qián)的時(shí)候,就必須跨單元調(diào)用Regional Zone 02的賬務(wù)服務(wù)。圖中用紅線(xiàn)表示耗時(shí)很長(zhǎng)(幾十毫秒級(jí))的異地訪(fǎng)問(wèn)。
從宏觀耗時(shí)示意圖上就可以比較容易地理解單元化的思想了:單元內(nèi)高內(nèi)聚,單元間低耦合,跨單元調(diào)用無(wú)法避免,但應(yīng)該盡量限定在少數(shù)的服務(wù)層調(diào)用,把整體耗時(shí)控制在可接受的范圍內(nèi)(包括對(duì)直接用戶(hù)體驗(yàn)和對(duì)整體吞吐量的影響)。
前面講的是正常情況下如何“多活”,機(jī)房故障情況下就要發(fā)揮單元之間的容災(zāi)互備作用了。
一個(gè)城市整體故障的情況下,應(yīng)用層流量通過(guò)規(guī)則的切換,由事先規(guī)劃好的其他單元接管。
數(shù)據(jù)層則是依靠自研的基于Paxos協(xié)議的分布式數(shù)據(jù)庫(kù)OceanBase,自動(dòng)把對(duì)應(yīng)容災(zāi)單元的從節(jié)點(diǎn)選舉為主節(jié)點(diǎn),實(shí)現(xiàn)應(yīng)用分片和數(shù)據(jù)分片繼續(xù)收斂在同一單元的效果。我們之所以規(guī)劃為“兩地三中心”“三地五中心”這樣的物理架構(gòu),實(shí)際上也是跟OceanBase的副本分布策略息息相關(guān)的。數(shù)據(jù)層異地多活,又是另一個(gè)宏大的課題了,以后可以專(zhuān)題分享,這里只簡(jiǎn)略提過(guò)。
這樣,借助單元化異地多活架構(gòu),才能實(shí)現(xiàn)開(kāi)頭展示的“26秒完成城市級(jí)容災(zāi)切換”能力。
關(guān)鍵技術(shù)組件
單元化是個(gè)復(fù)雜的系統(tǒng)工程,需要多個(gè)組件協(xié)同工作,從上到下涉及到DNS層、反向代理層、網(wǎng)關(guān)/WEB層、服務(wù)層、數(shù)據(jù)訪(fǎng)問(wèn)層。
總體指導(dǎo)思想是“多層防線(xiàn),迷途知返”。每層只要能獲取到足夠的信息,就盡早將請(qǐng)求轉(zhuǎn)到正確的單元去,如果實(shí)在拿不到足夠的信息,就靠下一層。
DNS層照理說(shuō)感知不到任何業(yè)務(wù)層的信息,但我們做了一個(gè)優(yōu)化叫“多域名技術(shù)”。比如PC端收銀臺(tái)的域名是cashier.alipay.com,在系統(tǒng)已知一個(gè)用戶(hù)數(shù)據(jù)屬于哪個(gè)單元的情況下,就讓其直接訪(fǎng)問(wèn)一個(gè)單獨(dú)的域名,直接解析到對(duì)應(yīng)的數(shù)據(jù)中心,避免了下層的跨機(jī)房轉(zhuǎn)發(fā)。例如上圖中的cashiergtj.alipay.com,gtj就是內(nèi)部一個(gè)數(shù)據(jù)中心的編號(hào)。移動(dòng)端也可以靠下發(fā)規(guī)則到客戶(hù)端來(lái)實(shí)現(xiàn)類(lèi)似的效果。
反向代理層是基于Nginx二次開(kāi)發(fā)的,后端系統(tǒng)在通過(guò)參數(shù)識(shí)別用戶(hù)所屬的單元之后,在Cookie中寫(xiě)入特定的標(biāo)識(shí)。下次請(qǐng)求,反向代理層就可以識(shí)別,直接轉(zhuǎn)發(fā)到對(duì)應(yīng)的單元。
網(wǎng)關(guān)/Web層是應(yīng)用上的第一道防線(xiàn),是真正可以有業(yè)務(wù)邏輯的地方。在通用的HTTP攔截器中識(shí)別Session中的用戶(hù)ID字段,如果不是本單元的請(qǐng)求,就 forward到正確的單元。并在Cookie中寫(xiě)入標(biāo)識(shí),下次請(qǐng)求在反向代理層就可以正確轉(zhuǎn)發(fā)。
服務(wù)層RPC框架和注冊(cè)中心內(nèi)置了對(duì)單元化能力的支持,可以根據(jù)請(qǐng)求參數(shù),透明地找到正確單元的服務(wù)提供方。
數(shù)據(jù)訪(fǎng)問(wèn)層是最后的兜底保障,即使前面所有的防線(xiàn)都失敗了,一筆請(qǐng)求進(jìn)入了錯(cuò)誤的單元,在訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的時(shí)候也一定會(huì)去正確的庫(kù)表,最多耗時(shí)變長(zhǎng),但絕對(duì)不會(huì)訪(fǎng)問(wèn)到錯(cuò)誤的數(shù)據(jù)。
這么多的組件要協(xié)同工作,必須共享同一份規(guī)則配置信息。必須有一個(gè)全局的單元化規(guī)則管控中心來(lái)管理,并通過(guò)一個(gè)高效的配置中心下發(fā)到分布式環(huán)境中的所有節(jié)點(diǎn)。
規(guī)則的內(nèi)容比較豐富,描述了城市、機(jī)房、邏輯單元的拓?fù)浣Y(jié)構(gòu),更重要的是描述了分片ID與邏輯單元之間的映射關(guān)系。
服務(wù)注冊(cè)中心內(nèi)置了單元字段,所有的服務(wù)提供者節(jié)點(diǎn)都帶有“邏輯單元”屬性。不同機(jī)房的注冊(cè)中心之間互相同步數(shù)據(jù),最終所有服務(wù)消費(fèi)者都知道每個(gè)邏輯單元的服務(wù)提供者有哪些。RPC框架就可以根據(jù)需要選擇調(diào)用目標(biāo)。
RPC框架本身是不理解業(yè)務(wù)邏輯的,要想知道應(yīng)該調(diào)哪個(gè)單元的服務(wù),信息只能從業(yè)務(wù)參數(shù)中來(lái)。如果是從頭設(shè)計(jì)的框架,可能直接約定某個(gè)固定的參數(shù)代表分片ID,要求調(diào)用者必須傳這個(gè)參數(shù)。但是單元化是在業(yè)務(wù)已經(jīng)跑了好多年的情況下的架構(gòu)改造,不可能讓所有存量服務(wù)修改接口。要求調(diào)用者在調(diào)用遠(yuǎn)程服務(wù)之前把分片ID放到ThreadLocal中?這樣也很不優(yōu)雅,違背了RPC框架的透明原則。
于是我們的解決方案是框架定義一個(gè)接口,由服務(wù)提供方給出一個(gè)實(shí)現(xiàn)類(lèi),描述如何從業(yè)務(wù)參數(shù)中獲取分片ID。服務(wù)提供方在接口上打注解,告訴框架實(shí)現(xiàn)類(lèi)的路徑。框架就可以在執(zhí)行RPC調(diào)用的時(shí)候,根據(jù)注解的實(shí)現(xiàn),從參數(shù)中截出分片ID。再結(jié)合全局路由規(guī)則中分片ID與邏輯單元之間的映射關(guān)系,就知道該選擇哪個(gè)單元的服務(wù)提供方了。
寫(xiě)在最后
本文著重介紹了螞蟻金服異地多活單元化架構(gòu)的原理,以及微服務(wù)體系在此架構(gòu)下的關(guān)鍵技術(shù)實(shí)現(xiàn)。要在工程層面真正落地單元化,涉及的技術(shù)問(wèn)題遠(yuǎn)不止此。例如:數(shù)據(jù)層如何容災(zāi)?無(wú)法水平拆分的業(yè)務(wù)如何處理?
螞蟻技術(shù)團(tuán)隊(duì)會(huì)堅(jiān)持走技術(shù)開(kāi)放路線(xiàn),后續(xù)還會(huì)以不同的形式分享相關(guān)話(huà)題,也歡迎各位讀者留言探討。
總結(jié)
以上是生活随笔為你收集整理的从“被动挖光缆”到“主动剪网线”,蚂蚁金服异地多活的微服务体系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 基于php的网上书店系统,基于PHP的网
- 下一篇: 用AntlR4实现简单的汇编编译器