100Wqps異地多活,得物是怎么架構(gòu)的? | 您所在的位置:網(wǎng)站首頁(yè) › 屬羊人生于正月好不好 › 100Wqps異地多活,得物是怎么架構(gòu)的? |
說(shuō)在前面
在40歲老架構(gòu)師尼恩的數(shù)千讀者群中,一直在指導(dǎo)大家簡(jiǎn)歷和職業(yè)升級(jí),前幾天,指導(dǎo)了一個(gè)華為老伙伴的簡(jiǎn)歷,小伙伴的優(yōu)勢(shì)在異地多活,但是在簡(jiǎn)歷指導(dǎo)的過(guò)程中,尼恩發(fā)現(xiàn): 異地多活的概念、異地多活的架構(gòu)、非常重要,但是小伙伴卻對(duì)整個(gè)異地多活的體系,不是太清晰。 異地多活的概念有很雜亂,像什么同城雙活、兩地三中心、三地五中心等等 這里 ,尼恩 站在 得物 異地多活架構(gòu)(得物架構(gòu)師 YINJIHUAN)的基礎(chǔ)上, 給大家對(duì)異地多活,做一個(gè)起底式的 、系統(tǒng)化、穿透式的介紹。 并且,把此文的異地多活架構(gòu),和尼恩其他的架構(gòu)文章一起,組成一個(gè)架構(gòu)知識(shí)系統(tǒng),幫助大家實(shí)現(xiàn)你的 架構(gòu)自由: 《吃透8圖1模板,人人可以做架構(gòu)》 《10Wqps評(píng)論中臺(tái),如何架構(gòu)?B站是這么做的!!!》 《阿里二面:千萬(wàn)級(jí)、億級(jí)數(shù)據(jù),如何性能優(yōu)化? 教科書(shū)級(jí) 答案來(lái)了》 《峰值21WQps、億級(jí)DAU,小游戲《羊了個(gè)羊》是怎么架構(gòu)的?》 《100億級(jí)訂單怎么調(diào)度,來(lái)一個(gè)大廠的極品方案》 《2個(gè)大廠 100億級(jí) 超大流量 紅包 架構(gòu)方案》 以上的架構(gòu)系列文章,非常重要,建議大家多多看看。 以上文章的PDF版本,都可以在《技術(shù)自由圈》公眾號(hào)找尼恩來(lái)獲取。 言歸正傳。 本文目錄 文章目錄 說(shuō)在前面本文目錄1. 什么是異地多活架構(gòu)設(shè)計(jì)的3高原則常見(jiàn)的多活方案常見(jiàn)方案1:同城雙活常見(jiàn)方案2:兩地三中心常見(jiàn)方案2:三地五中心異地多活3大挑戰(zhàn)1、數(shù)據(jù)同步延遲挑戰(zhàn)2、單元化解耦挑戰(zhàn)3、流量的路由挑戰(zhàn) 2. 得物APP的異地多活改造2.1得物APP異地多活基礎(chǔ)改造改造之前的單機(jī)房架構(gòu)得物APP機(jī)房改造得物APP單元化改造得物APP流量調(diào)度 2.2 RPC框架的異地多活改造2.2.1 定義RPC路由類型2.2.2 業(yè)務(wù)RPC改造2.2.4 遇到的問(wèn)題 2.3 數(shù)據(jù)庫(kù)的異地多活2.3.1 DB-Proxy代理中間件2.3.2 分布式ID2.3.3 使用OTTER進(jìn)行數(shù)據(jù)同步2.3.4 業(yè)務(wù)改造2.3.5 遇到的問(wèn)題 2.4 Redis 的異地多活2.4.1 業(yè)務(wù)改造2.4.2 遇到的問(wèn)題 2.5 RocketMQ異地多活2.5.1 定義消費(fèi)類型2.5.2 業(yè)務(wù)改造2.5.3 遇到的問(wèn)題 3. 得物異地多活的半單元化3.1 整體方向3.2 服務(wù)類型3.2.1 中心服務(wù)3.2.2 單元服務(wù)3.2.3 中心單元服務(wù) 4. 異地多活切流方案5. 得物異地多活的總結(jié)技術(shù)自由的實(shí)現(xiàn)路徑:實(shí)現(xiàn)你的 架構(gòu)自由:實(shí)現(xiàn)你的 響應(yīng)式 自由:實(shí)現(xiàn)你的 spring cloud 自由:實(shí)現(xiàn)你的 linux 自由:實(shí)現(xiàn)你的 網(wǎng)絡(luò) 自由:實(shí)現(xiàn)你的 分布式鎖 自由:實(shí)現(xiàn)你的 王者組件 自由:實(shí)現(xiàn)你的 面試題 自由: 1. 什么是異地多活異地多活的概念很多,像什么同城雙活、兩地三中心、三地五中心等等概念。 要想理解異地多活,需要從架構(gòu)設(shè)計(jì)的3高原則說(shuō)起。 架構(gòu)設(shè)計(jì)的3高原則現(xiàn)如今,開(kāi)發(fā)一個(gè)軟件系統(tǒng),對(duì)其要求越來(lái)越高,如果你了解一些「架構(gòu)設(shè)計(jì)」的要求,就知道一個(gè)好的軟件架構(gòu)應(yīng)該遵循以下 3 個(gè)原則: 高性能高并發(fā)高可用高性能意味著系統(tǒng)擁有更大流量的處理能力,更低的響應(yīng)延遲。 例如 1 秒可處理 10W 并發(fā)請(qǐng)求,接口響應(yīng)時(shí)間 5 ms 等等。 高并發(fā)表示系統(tǒng)在迭代新功能時(shí),能以最小的代價(jià)去擴(kuò)展,系統(tǒng)遇到流量壓力時(shí),可以在不改動(dòng)代碼的前提下,去擴(kuò)容系統(tǒng)。 高可用通常用 2 個(gè)指標(biāo)來(lái)衡量: 平均故障間隔 MTBF(Mean Time Between Failure):表示兩次故障的間隔時(shí)間,也就是系統(tǒng)「正常運(yùn)行」的平均時(shí)間,這個(gè)時(shí)間越長(zhǎng),說(shuō)明系統(tǒng)穩(wěn)定性越高故障恢復(fù)時(shí)間 MTTR(Mean Time To Repair):表示系統(tǒng)發(fā)生故障后「恢復(fù)的時(shí)間」,這個(gè)值越小,故障對(duì)用戶的影響越小可用性與這兩者的關(guān)系: 可用性(Availability)= MTBF / (MTBF + MTTR) * 100% 這個(gè)公式得出的結(jié)果是一個(gè)「比例」,通常我們會(huì)用「N 個(gè) 9」來(lái)描述一個(gè)系統(tǒng)的可用性。 從這張圖你可以看到,要想達(dá)到 4 個(gè) 9 以上的可用性,一年的不可以時(shí)間為 52分鐘,平均每天故障時(shí)間必須控制在 10 秒以內(nèi)。 系統(tǒng)發(fā)生故障其實(shí)是不可避免的,尤其是規(guī)模越大的系統(tǒng),發(fā)生問(wèn)題的概率也越大。 這些故障一般體現(xiàn)在 3 個(gè)方面: 硬件故障:CPU、內(nèi)存、磁盤(pán)、網(wǎng)卡、交換機(jī)、路由器軟件問(wèn)題:代碼 Bug、版本迭代不可抗力:地震、水災(zāi)、火災(zāi)、戰(zhàn)爭(zhēng)這些風(fēng)險(xiǎn)隨時(shí)都有可能發(fā)生。所以,在面對(duì)故障時(shí),我們的系統(tǒng)能否以「最快」的速度恢復(fù),就成為了可用性的關(guān)鍵。 常見(jiàn)的多活方案4 個(gè) 9 高可用的核心方案就是異地多活 異地多活指分布在異地的多個(gè)站點(diǎn)同時(shí)對(duì)外提供服務(wù)的業(yè)務(wù)場(chǎng)景。 異地多活是高可用架構(gòu)設(shè)計(jì)的一種,與傳統(tǒng)的災(zāi)備設(shè)計(jì)的最主要區(qū)別在于“多活”,即所有站點(diǎn)都是同時(shí)在對(duì)外提供服務(wù)的。 常見(jiàn)的多活方案有同城雙活、兩地三中心、三地五中心等多種技術(shù)方案, 常見(jiàn)方案1:同城雙活同城雙活是在同城或相近區(qū)域內(nèi)建立兩個(gè)機(jī)房。同城雙機(jī)房距離比較近,通信線路質(zhì)量較好,比較容易實(shí)現(xiàn)數(shù)據(jù)的同步復(fù)制 ,保證高度的數(shù)據(jù)完整性和數(shù)據(jù)零丟失。 同城兩個(gè)機(jī)房各承擔(dān)一部分流量,一般入口流量完全隨機(jī),內(nèi)部RPC調(diào)用盡量通過(guò)就近路由閉環(huán)在同機(jī)房,相當(dāng)于兩個(gè)機(jī)房鏡像部署了兩個(gè)獨(dú)立集群,數(shù)據(jù)仍然是單點(diǎn)寫(xiě)到主機(jī)房數(shù)據(jù)庫(kù),然后實(shí)時(shí)同步到另外一個(gè)機(jī)房。 下圖展示了同城雙活簡(jiǎn)單部署架構(gòu),當(dāng)然一般真實(shí)部署和考慮問(wèn)題要遠(yuǎn)遠(yuǎn)比下圖復(fù)雜。 服務(wù)調(diào)用基本在同機(jī)房?jī)?nèi)完成閉環(huán),數(shù)據(jù)仍然是單點(diǎn)寫(xiě)到主機(jī)房數(shù)據(jù)儲(chǔ)存,然后實(shí)時(shí)同步復(fù)制到同城備份機(jī)房。 當(dāng)機(jī)房A出現(xiàn)問(wèn)題時(shí)候運(yùn)維人員只需要通過(guò)GSLB或者其他方案手動(dòng)更改路由方式將流量路由到B機(jī)房。 同城雙活可有效用于防范火災(zāi)、建筑物破壞、供電故障、計(jì)算機(jī)系統(tǒng)及人為破壞引起的機(jī)房災(zāi)難。 同城雙活中的核心組件GSLB的原理,可以參見(jiàn) 尼恩的高并三部曲 之三《Java高并發(fā)核心編程 卷3 加強(qiáng)版》PDF。 常見(jiàn)方案2:兩地三中心所謂兩地三中心是指 同城雙中心 + 異地災(zāi)備中心。 異地災(zāi)備中心是指在異地的城市建立一個(gè)備份的災(zāi)備中心,用于雙中心的數(shù)據(jù)備份,數(shù)據(jù)和服務(wù)平時(shí)都是冷的, 當(dāng)雙中心所在城市或者地區(qū)出現(xiàn)異常而都無(wú)法對(duì)外提供服務(wù)的時(shí)候,異地災(zāi)備中心可以用備份數(shù)據(jù)進(jìn)行業(yè)務(wù)的恢復(fù)。 兩地三中心方案特點(diǎn) 優(yōu)勢(shì) 服務(wù)同城雙活,數(shù)據(jù)同城災(zāi)備,同城不丟失數(shù)據(jù)情況下跨機(jī)房級(jí)別容災(zāi)。架構(gòu)方案較為簡(jiǎn)單,核心是解決底層數(shù)據(jù)雙活,由于雙機(jī)房距離近,通信質(zhì)量好,底層儲(chǔ)存例如mysql可以采用同步復(fù)制,有效保證雙機(jī)房數(shù)據(jù)一致性。災(zāi)備中心能防范同城雙中心同時(shí)出現(xiàn)故障時(shí)候利用備份數(shù)據(jù)進(jìn)行業(yè)務(wù)的恢復(fù)。劣勢(shì) 數(shù)據(jù)庫(kù)寫(xiě)數(shù)據(jù)存在跨機(jī)房調(diào)用,在復(fù)雜業(yè)務(wù)以及鏈路下頻繁跨機(jī)房調(diào)用增加響應(yīng)時(shí)間,影響系統(tǒng)性能和用戶體驗(yàn)。服務(wù)規(guī)模足夠大(例如單體應(yīng)用超過(guò)萬(wàn)臺(tái)機(jī)器),所有機(jī)器鏈接一個(gè)主數(shù)據(jù)庫(kù)實(shí)例會(huì)引起連接不足問(wèn)題。出問(wèn)題不敢輕易將流量切往異地?cái)?shù)據(jù)備份中心,異地的備份數(shù)據(jù)中心是冷的,平時(shí)沒(méi)有流量進(jìn)入,因此出問(wèn)題需要較長(zhǎng)時(shí)間對(duì)異地災(zāi)備機(jī)房進(jìn)行驗(yàn)證。同城雙活和兩地三中心建設(shè)方案建設(shè)復(fù)雜度都不高,兩地三中心相比同城雙活有效解決了異地?cái)?shù)據(jù)災(zāi)備問(wèn)題,但是依然不能解決同城雙活存在的多處缺點(diǎn),想要解決這兩種架構(gòu)存在的弊端就要引入更復(fù)雜的解決方案去解決這些問(wèn)題。 常見(jiàn)方案2:三地五中心三地五中心和兩地三中心 的架構(gòu)差不太多,這里不做展開(kāi), 有興趣的小伙伴,可以來(lái)尼恩的瘋狂創(chuàng)客圈 高并發(fā)社群交流。 異地多活3大挑戰(zhàn)(1)應(yīng)用要走向異地,首先要面對(duì)的便是物理距離帶來(lái)的延時(shí)。 如果某個(gè)應(yīng)用請(qǐng)求需要在異地多個(gè)單元對(duì)同一行記錄進(jìn)行修改,為滿足異地單元間數(shù)據(jù)庫(kù)數(shù)據(jù)的一致性和完整性,需要付出高昂的時(shí)間成本。 (2)解決異地高延時(shí)即要做到單元內(nèi)數(shù)據(jù)讀寫(xiě)封閉,不能出現(xiàn)不同單元對(duì)同一行數(shù)據(jù)進(jìn)行修改,所以我們需要找到一個(gè)維度去劃分單元。 (3)某個(gè)單元內(nèi)訪問(wèn)其他單元數(shù)據(jù)需要能正確路由到對(duì)應(yīng)的單元,例如A用戶給B用戶轉(zhuǎn)賬,A用戶和B用戶數(shù)據(jù)不在一個(gè)單元內(nèi),對(duì)B用戶的作能路由到相應(yīng)的單元。 (4)面臨的數(shù)據(jù)同步挑戰(zhàn),對(duì)于單元封閉的數(shù)據(jù)需全部同步到對(duì)應(yīng)單元,對(duì)于讀寫(xiě)分離類型的,我們要把中心的數(shù)據(jù)同步到單元。 2、單元化解耦挑戰(zhàn)所謂單元(下面我們用RZone代替),是指一個(gè)能完成所有業(yè)務(wù)作的自包含集合,在這個(gè)集合中包含了所有業(yè)務(wù)所需的所有服務(wù),以及分配給這個(gè)單元的數(shù)據(jù)。 單元化架構(gòu)就是把單元作為系統(tǒng)部署的基本單位,在全站所有機(jī)房中部署數(shù)個(gè)單元,每個(gè)機(jī)房里的單元數(shù)目不定,任意一個(gè)單元都部署了系統(tǒng)所需的所有的應(yīng)用。 單元化架構(gòu)下,服務(wù)仍然是分層的,不同的是每一層中的任意一個(gè)節(jié)點(diǎn)都屬于且僅屬于某一個(gè)單元,上層調(diào)用下層時(shí),僅會(huì)選擇本單元內(nèi)的節(jié)點(diǎn)。 選擇什么維度來(lái)進(jìn)行流量切分,要從業(yè)務(wù)本身入手去分析。 例如電商業(yè)務(wù)和金融的業(yè)務(wù),最重要的流程即下單、支付、交易流程,通過(guò)對(duì)用戶id進(jìn)行數(shù)據(jù)切分拆分是最好的選擇,買(mǎi)家的相關(guān)作都會(huì)在買(mǎi)家所在的本單元內(nèi)完成。 對(duì)于商家相關(guān)作則無(wú)法進(jìn)行單元化,需要按照下面介紹的非單元化模式去部署。 當(dāng)然用戶作業(yè)務(wù)并非完全能避免跨單元甚至是跨機(jī)房調(diào)用,例如兩個(gè)買(mǎi)家A和B轉(zhuǎn)賬業(yè)務(wù),A和B所屬數(shù)據(jù)單元不一致的時(shí)候,對(duì)B進(jìn)行作就需要跨單元去完成,后面我們會(huì)介紹跨單元調(diào)用服務(wù)路由問(wèn)題。 3、流量的路由挑戰(zhàn) 流量調(diào)度,系統(tǒng)部署過(guò)去后流量怎么跟著怎么過(guò)去。流量自閉環(huán)。由于距離的原因,跨地域的物理延時(shí)是沒(méi)法避免的,流量過(guò)去之后怎么保證所有的作都在本地完成,如果做不到那怎么將這種延時(shí)影響降到最低。容災(zāi)切流。當(dāng)某個(gè)機(jī)房出現(xiàn)故障時(shí),如何快速把流量無(wú)損地切至其他機(jī)房。這里并不是說(shuō)簡(jiǎn)單把流量切過(guò)去就完事,由于數(shù)據(jù)在多區(qū)域同步,流量切過(guò)去之后能否保證數(shù)據(jù)的一致性? 2. 得物APP的異地多活改造 2.1得物APP異地多活基礎(chǔ)改造 改造之前的單機(jī)房架構(gòu)了解改造點(diǎn)之前我們先來(lái)看下目前單機(jī)房的現(xiàn)狀是什么樣子,才能更好的幫助大家去理解為什么要做這些改造。 如上圖所示,客戶端的請(qǐng)求進(jìn)來(lái)會(huì)先到SLB(負(fù)載均衡),然后到我們內(nèi)部的網(wǎng)關(guān),通過(guò)網(wǎng)關(guān)再分發(fā)到具體的業(yè)務(wù)服務(wù)。 業(yè)務(wù)服務(wù)會(huì)依賴Redis, Mysql, MQ, Nacos等中間件。 改造之后的目標(biāo) 既然做異地多活,那么必然是在不同地區(qū)有不同的機(jī)房,比如中心機(jī)房,單元機(jī)房。 所以我們要實(shí)現(xiàn)的效果如下圖所示: 得物多活改造一期目前有兩個(gè)機(jī)房,分別是機(jī)房A和機(jī)房B。 A機(jī)房我們定義為中心機(jī)房,也就是多活上線之前正在使用的機(jī)房。 另一個(gè)B機(jī)房,在描述的時(shí)候可能會(huì)說(shuō)成單元機(jī)房,那指的就是B機(jī)房。 得物APP單元化改造得物多活進(jìn)行了業(yè)務(wù)的單元改造,他們的業(yè)務(wù)比較單一,就是電商業(yè)務(wù),所以:一個(gè)機(jī)房就是一個(gè)單元,或者說(shuō),一個(gè)單元就是一個(gè)機(jī)房,在這個(gè)單元內(nèi)能夠完成業(yè)務(wù)的閉環(huán)。 比如說(shuō)用戶進(jìn)入APP,瀏覽商品,選擇商品確認(rèn)訂單,下單,支付,查看訂單信息,這整個(gè)流程都在一個(gè)單元中能夠完成,并且數(shù)據(jù)也是存儲(chǔ)在這個(gè)單元里面。 這塊對(duì)他們的難度不大。 得物APP流量調(diào)度用戶的請(qǐng)求,從客戶端發(fā)出,這個(gè)用戶的請(qǐng)求該到哪個(gè)機(jī)房,這是得物APP要改造的第一個(gè)點(diǎn)。 沒(méi)做多活之前,域名會(huì)解析到一個(gè)機(jī)房?jī)?nèi),做了多活后,域名會(huì)隨機(jī)解析到不同的機(jī)房中。 如果按照這種隨機(jī)的方式是肯定有問(wèn)題的,對(duì)于服務(wù)的調(diào)用是無(wú)所謂的,因?yàn)闆](méi)有狀態(tài)。 但是服務(wù)內(nèi)部依賴的存儲(chǔ)是有狀態(tài)的呀。 得物APP是電商業(yè)務(wù),用戶在中心機(jī)房下了一個(gè)單,然后跳轉(zhuǎn)到訂單詳情,這個(gè)時(shí)候請(qǐng)求到了單元機(jī)房,底層數(shù)據(jù)同步有延遲,一訪問(wèn)報(bào)個(gè)錯(cuò):訂單不存在。 用戶當(dāng)場(chǎng)就懵了,錢(qián)都付了,訂單沒(méi)了。 所以針對(duì)同一個(gè)用戶,盡可能在一個(gè)機(jī)房?jī)?nèi)完成業(yè)務(wù)閉環(huán)。 為了解決流量調(diào)度的問(wèn)題,得物APP基于OpenResty二次開(kāi)發(fā)出了DLB流量網(wǎng)關(guān),DLB會(huì)對(duì)接多活控制中心, DLB流量網(wǎng)關(guān)能夠知道當(dāng)前訪問(wèn)的用戶是屬于哪個(gè)機(jī)房,如果用戶不屬于當(dāng)前機(jī)房,DLB會(huì)直接將請(qǐng)求路由到該用戶所屬機(jī)房?jī)?nèi)的DLB。 如果每次都隨機(jī)到固定的機(jī)房,再通過(guò)DLB去校正,必然會(huì)存在跨機(jī)房請(qǐng)求,耗時(shí)加長(zhǎng)。 所以在這塊得物APP也是結(jié)合客戶端做了一些優(yōu)化,在DLB校正請(qǐng)求后,得物APP會(huì)將用戶對(duì)應(yīng)的機(jī)房IP直接通過(guò)Header響應(yīng)給客戶端。 這樣下次請(qǐng)求的時(shí)候,客戶端就可以直接通過(guò)這個(gè)IP訪問(wèn)。 如果用戶當(dāng)前訪問(wèn)的機(jī)房掛了,客戶端需要降級(jí)成之前的域名訪問(wèn)方式,通過(guò)DNS解析到存活的機(jī)房。 2.2 RPC框架的異地多活改造當(dāng)用戶的請(qǐng)求達(dá)到了單元機(jī)房?jī)?nèi),理論上后續(xù)所有的作都是在單元機(jī)房完成。 這就要求RPC請(qǐng)求落在就近的機(jī)房,那么,怎么知道單元機(jī)房的服務(wù)信息 所以得物APP的注冊(cè)中心(Nacos)要做雙向同步,這樣才能拿到所有機(jī)房的服務(wù)信息。 不同的機(jī)房的Nacos,服務(wù)的注冊(cè)信息采用雙向復(fù)制,進(jìn)行同步。 前面也提到了,用戶的請(qǐng)求盡量在一個(gè)機(jī)房?jī)?nèi)完成閉環(huán),當(dāng)然,只是盡量,沒(méi)有說(shuō)全部。 這是因?yàn)橛械臉I(yè)務(wù)場(chǎng)景不適合劃分單元,比如庫(kù)存扣減。 所以在得物APP的劃分里面,有一個(gè)機(jī)房是中心機(jī)房,那些不做多活的業(yè)務(wù)只會(huì)部署在中心機(jī)房里面,那么庫(kù)存扣減的時(shí)候就需要跨機(jī)房調(diào)用。 對(duì)于單元服務(wù)會(huì)存在多個(gè)機(jī)房的服務(wù)信息,如果不進(jìn)行控制,則會(huì)出現(xiàn)調(diào)用其他機(jī)房的情況,所以RPC框架要進(jìn)行改造。 2.2.1 定義RPC路由類型 默認(rèn)路由請(qǐng)求到中心機(jī)房,會(huì)優(yōu)先調(diào)用中心機(jī)房?jī)?nèi)的服務(wù),如果中心機(jī)房無(wú)此服務(wù),則調(diào)用單元機(jī)房的服務(wù),如果單元機(jī)房沒(méi)有此服務(wù)則直接報(bào)錯(cuò)。 單元路由請(qǐng)求到單元機(jī)房,那么說(shuō)明此用戶的流量規(guī)則是在單元機(jī)房,接下來(lái)所有的RPC調(diào)用都只會(huì)調(diào)用單元機(jī)房?jī)?nèi)的服務(wù),沒(méi)有服務(wù)則報(bào)錯(cuò)。 中心路由請(qǐng)求到單元機(jī)房,那么直接調(diào)用中心機(jī)房的服務(wù),中心機(jī)房沒(méi)有服務(wù)則報(bào)錯(cuò)。請(qǐng)求到中心機(jī)房,那么就本機(jī)房調(diào)用。 2.2.2 業(yè)務(wù)RPC改造業(yè)務(wù)方需要對(duì)自己的接口(Java interface)進(jìn)行標(biāo)記是什么類型,是單元路由,還是中心路由,通過(guò)@HARoute加在接口上面。 標(biāo)記完成后,在Dubbo接口進(jìn)行注冊(cè)的時(shí)候,會(huì)把路由類型放入到這個(gè)接口的元數(shù)據(jù)里面。 在Nacos后臺(tái)可以查看Dubbo接口的路由類型,這些數(shù)據(jù),也是RPC路由異地多活改造的核心參數(shù)。 后面通過(guò)RPC調(diào)用接口內(nèi)部所有的方法都會(huì)按照標(biāo)記類型進(jìn)行路由。 比如,單元路由的RPC,RPC在路由的時(shí)候會(huì)根據(jù)這個(gè)值判斷用戶所在的機(jī)房。 路由邏輯如下: RPC 接口復(fù)制一份,命名為UnitApi,帶上路由參數(shù)。在新接口的實(shí)現(xiàn)里面調(diào)用老接口,新舊接口共存。 2.2.4 遇到的問(wèn)題1 其他場(chǎng)景切單元接口 除了RPC直接調(diào)用的接口,還有一大部分是通過(guò)Dubbo泛化過(guò)來(lái)的,這塊在上線后也需要將流量切到UnitApi,等老接口沒(méi)有請(qǐng)求量之后才能下線。 2 接口分類整改 接口進(jìn)行分類,之前沒(méi)有多活的約束,一個(gè)Java interface中的方法可能各種各樣,所以需要進(jìn)行rpc 接口的分類整改 3 業(yè)務(wù)層面調(diào)整 業(yè)務(wù)層面調(diào)整,比如之前查詢訂單只需要一個(gè)訂單號(hào),但是現(xiàn)在需要路由參數(shù),所以接入這個(gè)接口的上游都需要調(diào)整。 2.3 數(shù)據(jù)庫(kù)的異地多活請(qǐng)求順利的到達(dá)了服務(wù)層,接下來(lái)要跟數(shù)據(jù)庫(kù)打交道了。 數(shù)據(jù)庫(kù)得物APP定義了不同的類型,定義如下: 1 單元化 此庫(kù)為單元庫(kù),會(huì)同時(shí)在兩個(gè)機(jī)房部署,每個(gè)機(jī)房都有完整的數(shù)據(jù),數(shù)據(jù)采用雙向同步。 2 中心化 此庫(kù)為中心庫(kù),只會(huì)在中心機(jī)房部署。 3 中心單元化 此庫(kù)為中心單元庫(kù),會(huì)同時(shí)在兩個(gè)機(jī)房部署,中心可以讀寫(xiě),其他機(jī)房只能讀。 中心寫(xiě)數(shù)據(jù)后單向復(fù)制到另一個(gè)機(jī)房。 2.3.1 DB-Proxy代理中間件異地多活之前,得物內(nèi)部的各大服務(wù), 都是客戶端形式的Sharding中間件,客戶端模式訪問(wèn)分庫(kù)分表, 要命的是,每個(gè)業(yè)務(wù)方的版本還不一致。 在多活切流的過(guò)程中需要對(duì)數(shù)據(jù)庫(kù)禁寫(xiě)來(lái)保證業(yè)務(wù)數(shù)據(jù)的準(zhǔn)確性,如果沒(méi)有統(tǒng)一的中間件,這將是一件很麻煩的事情。 所以得物APP調(diào)整為 proxy模式,去掉 client模式的分庫(kù)分表訪問(wèn)。 得物APP 通過(guò)對(duì)ShardingSphere進(jìn)行深度定制,二次開(kāi)發(fā)數(shù)據(jù)庫(kù)代理proxy中間件 ,彩虹橋。 有了proxy組件之后,各業(yè)務(wù)方替換之前的Sharding Client方式。 單元化的庫(kù),數(shù)據(jù)層面會(huì)做雙向同步復(fù)制作。如果直接用表的自增ID則會(huì)出現(xiàn)下面的沖突問(wèn)題: 得物APP采用了一種一勞永逸的方式,接入全局唯一的分布式ID來(lái)避免主鍵的沖突。 所以,分布式ID絕對(duì)是 分庫(kù)分表的核心 技術(shù)要點(diǎn),如果做到 高并發(fā)、高性能、防止傾斜,絕對(duì)是一大核心的技術(shù)難題, 這里,強(qiáng)烈建議大家去看看尼恩 分析了百度ID、推特snowflake ID,shardingjdbc ID三大ID源碼之后,定義的異步高并發(fā)、防止傾斜、防止時(shí)間回?fù)艿母卟l(fā)ID,一定帶給大家N多的啟發(fā)。 2.3.3 使用OTTER進(jìn)行數(shù)據(jù)同步OTTER是阿里巴巴公司為了解決杭州/美國(guó)機(jī)房數(shù)據(jù)間同步研發(fā)的一個(gè)開(kāi)源軟件。 OTTER基于數(shù)據(jù)庫(kù)增量日志解析,準(zhǔn)實(shí)時(shí)同步到本機(jī)房或異地機(jī)房的mysql/oracle數(shù)據(jù)庫(kù),是一個(gè)分布式數(shù)據(jù)庫(kù)同步系統(tǒng)。 工作原理圖: 原理描述: 基于Canal開(kāi)源產(chǎn)品,獲取數(shù)據(jù)庫(kù)增量日志數(shù)據(jù)。典型管理系統(tǒng)架構(gòu),manager(web管理)+node(工作節(jié)點(diǎn)) a. manager運(yùn)行時(shí)推送同步配置到node節(jié)點(diǎn) b. node節(jié)點(diǎn)將同步狀態(tài)反饋到manager上基于zookeeper,解決分布式狀態(tài)調(diào)度的,允許多node節(jié)點(diǎn)之間協(xié)同工作 2.3.4 業(yè)務(wù)改造在Dao層對(duì)表進(jìn)行作的時(shí)候,會(huì)通過(guò)ThreadLocal設(shè)置當(dāng)前方法的ShardingKey,然后通過(guò)Mybatis攔截器機(jī)制,將ShardingKey通過(guò)Hint的方式放入SQL中,帶給彩虹橋。 彩虹橋會(huì)判斷當(dāng)前的ShardingKey是否屬于當(dāng)前機(jī)房,如果不是直接禁寫(xiě)報(bào)錯(cuò)。 這里跟大家簡(jiǎn)單的說(shuō)明下為什么切流過(guò)程中要禁寫(xiě),這個(gè)其實(shí)跟JVM的垃圾回收有點(diǎn)相似。如果不對(duì)作禁寫(xiě),那么就會(huì)不斷的產(chǎn)生數(shù)據(jù),而得物APP切流,一定要保證當(dāng)前機(jī)房的數(shù)據(jù)全部同步過(guò)去了之后才開(kāi)始生效流量規(guī)則,否則用戶切到另一個(gè)機(jī)房,數(shù)據(jù)沒(méi)同步完,就會(huì)產(chǎn)生業(yè)務(wù)問(wèn)題。除了彩虹橋會(huì)禁寫(xiě),RPC框架內(nèi)部也會(huì)根據(jù)流量規(guī)則進(jìn)行阻斷。 2.3.5 遇到的問(wèn)題1 單元接口中不能訪問(wèn)中心數(shù)據(jù)庫(kù) 如果接口標(biāo)記成了單元接口,那么只能作單元庫(kù)。 在以前沒(méi)有做多活改造的時(shí)候,基本上沒(méi)有什么中心和單元的概念,所有的表也都是放在一起的。 多活改造后,得物APP會(huì)根據(jù)業(yè)務(wù)場(chǎng)景對(duì)數(shù)據(jù)庫(kù)進(jìn)行劃分。 劃分后,中心庫(kù)只會(huì)被中心機(jī)房的程序使用,在單元機(jī)房是不允許連接中心庫(kù)。 所以單元接口里面如果涉及到對(duì)中心庫(kù)的作,必定會(huì)報(bào)錯(cuò)。 這塊需要調(diào)整成走中心的RPC接口。 2 中心接口不能訪問(wèn)單元數(shù)據(jù)庫(kù) 跟上面同樣的問(wèn)題,如果接口是中心的,也不能在接口里面作單元庫(kù)。中心接口的請(qǐng)求都會(huì)強(qiáng)制走到中心機(jī)房,如果里面有涉及到另一個(gè)機(jī)房的作,也必須走RPC接口進(jìn)行正確的路由, 因?yàn)槟阒行臋C(jī)房不能作另一個(gè)機(jī)房的數(shù)據(jù)庫(kù)。 3 批量查詢調(diào)整 比如批量根據(jù)訂單號(hào)進(jìn)行查詢,但是這些訂單號(hào)不是同一個(gè)買(mǎi)家。 如果隨便用一個(gè)訂單的買(mǎi)家作為路由參數(shù),那么其他一些訂單其實(shí)是屬于另一個(gè)單元的,這樣就有可能存在查詢到舊數(shù)據(jù)的問(wèn)題。 這樣批量查詢的場(chǎng)景,只能針對(duì)同一個(gè)買(mǎi)家可用,如果是不同的買(mǎi)家需要分批調(diào)用。 2.4 Redis 的異地多活Redis在業(yè)務(wù)中用的比較多,在多活的改造中也有很多地方需要調(diào)整。 對(duì)于Redis首先得物APP明確幾個(gè)定義: 不做雙向同步 Redis不會(huì)和數(shù)據(jù)庫(kù)一樣做雙向同步,也就是中心機(jī)房一個(gè)Redis集群,單元機(jī)房一個(gè)Redis集群。 每個(gè)機(jī)房的集群中只存在一部分用戶的緩存數(shù)據(jù),不是全量的。 Redis類型 Redis分為中心和單元,中心只會(huì)在中心機(jī)房部署,單元會(huì)在中心和單元兩個(gè)機(jī)房部署。 2.4.1 業(yè)務(wù)改造1 Redis多數(shù)據(jù)源支持 多活改造前,每個(gè)應(yīng)用都有一個(gè)單獨(dú)的Redis集群, 多活改造后,由于應(yīng)用沒(méi)有進(jìn)行單元化和中心的拆分,所以一個(gè)應(yīng)用中會(huì)存在需要連接兩個(gè)Redis的情況。 一個(gè)中心Redis,一個(gè)單元Redis。 基礎(chǔ)架構(gòu)組提供的專用Redis Client包,需要支持多數(shù)據(jù)源的創(chuàng)建, 基礎(chǔ)包中并且定義通用的配置格式,業(yè)務(wù)方只需要在自己 的配置里面指定集群和連接模式即可完成接入。 spring.redis.sources.carts.mode=unit spring.redis.sources.carts.cluster-name=cartsCuster具體的Redis實(shí)例信息會(huì)在配置中心統(tǒng)一維護(hù),不需要業(yè)務(wù)方關(guān)心, 在做機(jī)房擴(kuò)容的時(shí)候,業(yè)務(wù)方是不需要調(diào)整的 2 數(shù)據(jù)一致性 緩存和緩存之間,不進(jìn)行同步,沒(méi)有數(shù)據(jù)一致性問(wèn)題 緩存和DB之間,使用binlog 進(jìn)行同步 這里得物APP的方案是采用訂閱數(shù)據(jù)庫(kù)的binlog來(lái)進(jìn)行緩存的失效作,可以訂閱本機(jī)房的binlog,也可以訂閱其他機(jī)房的binlog來(lái)實(shí)現(xiàn)所有機(jī)房的緩存失效。 使用 binlog 進(jìn)行同步的實(shí),非常重要, 具體請(qǐng)參見(jiàn)尼恩的 100wQps 三級(jí)緩存組件實(shí),建議大家一定認(rèn)真看看。 2.4.2 遇到的問(wèn)題1 序列化協(xié)議兼容 在接入新的Redis Client包后,測(cè)試環(huán)境出現(xiàn)了老數(shù)據(jù)的兼容問(wèn)題。 有個(gè)別應(yīng)用自己定制了序列化方式,導(dǎo)致Redis按新的方式裝配后沒(méi)有用到自定義的協(xié)議,這塊也是進(jìn)行了改造,支持多數(shù)據(jù)源的協(xié)議自定義。 2 分布式鎖的使用 目前項(xiàng)目中的分布式鎖是基于Redis實(shí)現(xiàn),當(dāng)Redis有多個(gè)數(shù)據(jù)源之后,分布式鎖也需要進(jìn)行適配。 在使用的地方要區(qū)分場(chǎng)景,默認(rèn)都是用的中心Redis來(lái)加鎖。 但是單元接口里面的作都是買(mǎi)家場(chǎng)景,所以這部分需要調(diào)整為單元Redis鎖對(duì)象進(jìn)行加鎖,這樣能夠提高性能。其他的一些場(chǎng)景有涉及到全局資源的鎖定,那就用中心Redis鎖對(duì)象進(jìn)行加鎖。 2.5 RocketMQ異地多活所以MQ跟數(shù)據(jù)庫(kù)一樣,也要做同步,將消息同步到另一個(gè)機(jī)房的MQ中,至于另一個(gè)機(jī)房的消費(fèi)者要不要消費(fèi),這就要讓業(yè)務(wù)場(chǎng)景去決定。 1 中心訂閱 中心訂閱指的是消息無(wú)論是在中心機(jī)房發(fā)出的還是單元機(jī)房發(fā)出的,都只會(huì)在中心機(jī)房進(jìn)行消費(fèi)。 如果是單元機(jī)房發(fā)出的,會(huì)將單元的消息復(fù)制一份到中心進(jìn)行消費(fèi)。 2 普通訂閱 普通訂閱就是默認(rèn)的行為,指的是就近消費(fèi)。在中心機(jī)房發(fā)送的消息就由中心機(jī)房的消費(fèi)者進(jìn)行消費(fèi),在單元機(jī)房發(fā)送的消息就由單元機(jī)房的消費(fèi)進(jìn)行消費(fèi)。 3 單元訂閱 單元訂閱指的是消息會(huì)根據(jù)ShardingKey進(jìn)行消息的過(guò)濾,無(wú)論你在哪個(gè)機(jī)房發(fā)送消息,消息都會(huì)復(fù)制到另一個(gè)機(jī)房,此時(shí)兩個(gè)機(jī)房都有該消息。通過(guò)ShardingKey判斷當(dāng)前消息應(yīng)該被哪個(gè)機(jī)房消費(fèi),符合的才會(huì)進(jìn)行消費(fèi),不符合的框架層面會(huì)自動(dòng)ACK。 4 全單元訂閱 全單元訂閱指的是消息無(wú)論在哪個(gè)機(jī)房發(fā)出,都會(huì)在所有的機(jī)房進(jìn)行消費(fèi)。 2.5.2 業(yè)務(wù)改造1 消息發(fā)送方調(diào)整 消息發(fā)送方,需要結(jié)合業(yè)務(wù)場(chǎng)景進(jìn)行區(qū)分。如果是買(mǎi)家場(chǎng)景的業(yè)務(wù)消息,在發(fā)消息的時(shí)候需要將"多活路由Key"放入消息中,具體怎么消費(fèi)由消費(fèi)方?jīng)Q定。 如果消費(fèi)方是單元消費(fèi)的話那么必須依賴發(fā)送方的"多活路由Key",否則無(wú)法知道當(dāng)前消息應(yīng)該在哪個(gè)機(jī)房消費(fèi)。 2 消息消費(fèi)方指定消費(fèi)模式 前面提到了中心訂閱,單元訂閱,普通訂閱,全單元訂閱多種模式,到底要怎么選就是要結(jié)合業(yè)務(wù)場(chǎng)景來(lái)定的,定好后在配置MQ信息的時(shí)候指定即可。 比如中心訂閱就適合你整個(gè)服務(wù)都是中心的,其他機(jī)房都沒(méi)部署,這個(gè)時(shí)候肯定適合中心訂閱。 比如你要對(duì)緩存進(jìn)行清除,就比較適合全單元訂閱,一旦數(shù)據(jù)有變更,所有機(jī)房的緩存都清除掉。 2.5.3 遇到的問(wèn)題1 消息冪等消費(fèi) 就算不做多活,消息消費(fèi)場(chǎng)景,肯定是要做冪等處理的,因?yàn)橄⒈旧砭陀兄卦嚈C(jī)制。 單獨(dú)拎出來(lái)說(shuō)是在切流的過(guò)程中,屬于切流這部分用戶的消息會(huì)被復(fù)制到另一個(gè)機(jī)房重新進(jìn)行消費(fèi), 解釋下為什么切流過(guò)程中會(huì)有消息消費(fèi)失敗以及需要復(fù)制到另一個(gè)機(jī)房去處理,如下圖所示: 用戶在當(dāng)前機(jī)房進(jìn)行業(yè)務(wù)作后,會(huì)產(chǎn)生消息。由于是單元訂閱,所以會(huì)在當(dāng)前機(jī)房進(jìn)行消費(fèi)。 消費(fèi)過(guò)程中,發(fā)生了切流作,消費(fèi)邏輯里面對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀寫(xiě),但是單元表的作都攜帶了ShardingKey,彩虹橋會(huì)判斷ShardingKey是否符合當(dāng)前的規(guī)則,發(fā)現(xiàn)不符合直接禁寫(xiě)報(bào)錯(cuò)。 這批切流用戶的消息就全部消費(fèi)失敗。 等到流量切到另一個(gè)機(jī)房后,如果不進(jìn)行消息的重新投遞,那么這部分消息就丟失了,這就是為什么要復(fù)制到另一個(gè)機(jī)房進(jìn)行消息的重新投遞。 2 切流場(chǎng)景的消息順序問(wèn)題 上面講到了在切流過(guò)程中,會(huì)將消息復(fù)制到另一個(gè)機(jī)房進(jìn)行重新消費(fèi),然后是基于時(shí)間點(diǎn)去回放的,如果你的業(yè)務(wù)消息本身就是普通的Topic, 在消息回放的時(shí)候如果同一個(gè)場(chǎng)景的消息有多條,這個(gè)順序并不一定是按照之前的順序來(lái)消費(fèi),所以這里涉及到一個(gè)消費(fèi)順序的問(wèn)題。 如果你之前的業(yè)務(wù)場(chǎng)景本身就是用的順序消息,那么是沒(méi)問(wèn)題的,如果之前不是順序消息,這里就有可能有問(wèn)題,我舉個(gè)例子說(shuō)明下: 解決方案有下面幾種: Topic換成順序消息,以用戶進(jìn)行分區(qū),這樣就能保證每個(gè)用戶的消息嚴(yán)格按照發(fā)送順序進(jìn)行消費(fèi)對(duì)消息做冪等,已消費(fèi)過(guò)就不再消費(fèi)。但是這里跟普通的消息不同,會(huì)有N條消息,如果對(duì)msgId進(jìn)行存儲(chǔ),這樣就可以判斷是否消費(fèi)過(guò),但是這樣存儲(chǔ)壓力太大,當(dāng)然也可以只存儲(chǔ)最近N條來(lái)減小存儲(chǔ)壓力。消息冪等的優(yōu)化方式,讓消息發(fā)送方每發(fā)送一次,都帶一個(gè)version,version必須是遞增。消費(fèi)方消費(fèi)消息后把當(dāng)前version存儲(chǔ)起來(lái),消費(fèi)之前判斷消息的version是否大于存儲(chǔ)的version,滿足條件才進(jìn)行消費(fèi),這樣既避免了存儲(chǔ)的壓力也能滿足業(yè)務(wù)的需求。 3. 得物異地多活的半單元化得物異地多活的沒(méi)有做全單元化,而是半單元化 首先要根據(jù)整個(gè)多活的一個(gè)整體目標(biāo)和方向去梳理, 比如得物APP的整體方向就是買(mǎi)家交易的核心鏈路必須實(shí)現(xiàn)單元化改造。那么這整個(gè)鏈路所有依賴的上下游都需要改造。 用戶瀏覽商品,進(jìn)入確認(rèn)訂單,下單,支付,查詢訂單信息。這個(gè)核心鏈路其實(shí)涉及到了很多的業(yè)務(wù)域,比如:商品,出價(jià),訂單,支付,商家等等。 在這些已經(jīng)明確了的業(yè)務(wù)域下面,可能還有一些其他的業(yè)務(wù)域在支撐著,所以要把整體的鏈路都梳理出來(lái),一起改造。 當(dāng)然也不是所有的都必須做單元化,還是得看業(yè)務(wù)場(chǎng)景,比如庫(kù)存,肯定是在交易核心鏈路上,但是不需要改造,必須走中心。 3.2 服務(wù)類型 3.2.1 中心服務(wù)中心服務(wù)只會(huì)在中心機(jī)房部署,并且數(shù)據(jù)庫(kù)也一定是中心庫(kù)。 可以對(duì)整個(gè)應(yīng)用進(jìn)行打標(biāo)成中心,這樣外部訪問(wèn)這個(gè)服務(wù)的接口時(shí)都會(huì)被路由到中心機(jī)房。 3.2.2 單元服務(wù)單元服務(wù)會(huì)在中心機(jī)房和單元機(jī)房同時(shí)部署,并且數(shù)據(jù)庫(kù)也一定是單元庫(kù)。 單元服務(wù)是買(mǎi)家維度的業(yè)務(wù),比如確認(rèn)訂單,下單。 買(mǎi)家維度的業(yè)務(wù),在接口定義上,第一個(gè)參數(shù)必須是"多活路由Key",因?yàn)橐M(jìn)行路由。 用戶的請(qǐng)求已經(jīng)根據(jù)規(guī)則進(jìn)行分流到不同的機(jī)房,只會(huì)作對(duì)應(yīng)機(jī)房里面的數(shù)據(jù)庫(kù)。 中心單元服務(wù)也就是說(shuō)這個(gè)服務(wù)里面既有中心的接口也有單元的接口,并且數(shù)據(jù)庫(kù)也是有兩套。 所以這種服務(wù)其實(shí)也是要在兩個(gè)機(jī)房同時(shí)部署的,只不過(guò)是單元機(jī)房只會(huì)有單元接口過(guò)來(lái)的流量,中心接口是沒(méi)有流量的。 一些底層的支撐業(yè)務(wù),比如商品,商家這些就屬于中心單元服務(wù)。 支撐維度的業(yè)務(wù)是沒(méi)有"多活路由Key"的,商品是通用的,并不屬于某一個(gè)買(mǎi)家。 而支撐類型的業(yè)務(wù)底層的數(shù)據(jù)庫(kù)是中心單元庫(kù),也就是中心寫(xiě)單元讀,寫(xiě)請(qǐng)求是在中心進(jìn)行,比如商品的創(chuàng)建,修改等。 作后會(huì)同步到另一個(gè)機(jī)房的數(shù)據(jù)庫(kù)里面。這樣的好處就是可以減少得物APP在核心鏈路中的耗時(shí),如果商品不做單元化部署,那么瀏覽商品或者下單的時(shí)候查詢商品信息都必須走中心機(jī)房進(jìn)行讀取。 而現(xiàn)在則會(huì)就近路由進(jìn)行接口的調(diào)用,請(qǐng)求到中心機(jī)房就調(diào)中心機(jī)房的服務(wù),請(qǐng)求到單元機(jī)房就調(diào)單元機(jī)房的服務(wù),單元機(jī)房也是有數(shù)據(jù)庫(kù)的,不需要跨機(jī)房。 從長(zhǎng)遠(yuǎn)考慮,還是需要進(jìn)行拆分,把中心的業(yè)務(wù)和單元的業(yè)務(wù)拆開(kāi),這樣會(huì)比較清晰。 4. 異地多活切流方案所謂切流,就是在?個(gè)數(shù)據(jù)中心發(fā)生故障或?yàn)?zāi)難的情況下,將流量切換到其他數(shù)據(jù)中心,其他數(shù)據(jù)中心可以正常運(yùn)行并對(duì)關(guān)鍵業(yè)務(wù)或全部業(yè)務(wù)進(jìn)行接管,實(shí)現(xiàn)用戶的故障無(wú)感知。 前面得物APP也提到了再切流過(guò)程中,會(huì)禁寫(xiě),會(huì)復(fù)制MQ的消息到另一個(gè)機(jī)房重新消費(fèi)。 接下來(lái)給大家介紹下得物APP的切流方案,能夠幫助大家更深刻的理解整個(gè)多活的異常場(chǎng)景下處理流程。 當(dāng)需要切流的時(shí)候,作人員會(huì)通過(guò)雙活控制中心的后臺(tái)進(jìn)行作。 切流之前需要先進(jìn)行已有流量的清理,需要下發(fā)禁寫(xiě)規(guī)則。 禁寫(xiě)規(guī)則會(huì)下發(fā)到中心和單元兩個(gè)機(jī)房對(duì)應(yīng)的配置中心里面,通過(guò)配置中心去通知需要監(jiān)聽(tīng)的程序。 彩虹橋執(zhí)行禁寫(xiě)邏輯彩虹橋會(huì)用到禁寫(xiě)規(guī)則,當(dāng)禁寫(xiě)規(guī)則在配置中心修改后,彩虹橋能立馬感知到,然后會(huì)根據(jù)SQL中攜帶的shardingkey進(jìn)行規(guī)則的判斷,看當(dāng)前shardingkey是否屬于這個(gè)機(jī)房,如果不屬于則進(jìn)行攔截。 反饋禁寫(xiě)生效結(jié)果當(dāng)配置變更后會(huì)推送到彩虹橋,配置中心會(huì)感知到配置推送的結(jié)果,然后將生效的結(jié)果反饋給雙活控制中心。 推送禁寫(xiě)生效時(shí)間給Otter雙活控制中心收到所有的反饋后,會(huì)將全部生效的時(shí)間點(diǎn)通過(guò)MQ消息告訴Otter。 Otter進(jìn)行數(shù)據(jù)同步Otter收到消息會(huì)根據(jù)時(shí)間點(diǎn)進(jìn)行數(shù)據(jù)同步。 Otter同步完成反饋同步結(jié)果生效時(shí)間點(diǎn)之前的數(shù)據(jù)全部同步完成后會(huì)通過(guò)MQ消息反饋給雙活控制中心。 下發(fā)最新流量規(guī)則雙活中心收到Otter的同步完成的反饋消息后,會(huì)下發(fā)流量規(guī)則,流量規(guī)則會(huì)下發(fā)到DLB,RPC,彩虹橋。 后續(xù)用戶的請(qǐng)求就會(huì)直接被路由到正確的機(jī)房。 5. 得物異地多活的總結(jié)多活是一個(gè)高可用的容災(zāi)手段,但實(shí)現(xiàn)的成本和對(duì)技術(shù)團(tuán)隊(duì)的要求非常高。但是異地多活改造的范圍實(shí)在是太大了。 本篇主要講的是中間件層面和業(yè)務(wù)層面的一些改造點(diǎn)和過(guò)程,同時(shí)還有其他的一些點(diǎn)都沒(méi)有提到。 比如:機(jī)房網(wǎng)絡(luò)的建設(shè),發(fā)布系統(tǒng)支持多機(jī)房,監(jiān)控系統(tǒng)支持多機(jī)房的整個(gè)鏈路監(jiān)控,數(shù)據(jù)巡檢的監(jiān)控等等。 沒(méi)有100%的可用性,異地多活只是在極端場(chǎng)景下對(duì)業(yè)務(wù)的一些取舍罷了,優(yōu)先保證核心功能。 在實(shí)現(xiàn)多活的時(shí)候,得物APP應(yīng)該結(jié)合業(yè)務(wù)場(chǎng)景去進(jìn)行設(shè)計(jì),所以,也不是所有系統(tǒng),所有功能都要滿足多活的條件。 得物異地多活的方案很多很多, 大家有什么具體的問(wèn)題,也可以來(lái)尼恩的高并發(fā)社群(50+)里邊交流。 后續(xù),尼恩會(huì)給大家結(jié)合各大互聯(lián)網(wǎng)的行業(yè)案例,分析出更多,更加勁爆的異地多活,大家可以找尼恩來(lái)一次性獲取這些方案的PDF。 當(dāng)然,如果大家遇到這類高可用的面試難題,也可以找尼恩求助。 技術(shù)自由的實(shí)現(xiàn)路徑: 實(shí)現(xiàn)你的 架構(gòu)自由:《吃透8圖1模板,人人可以做架構(gòu)》 《10Wqps評(píng)論中臺(tái),如何架構(gòu)?B站是這么做的!!!》 《阿里二面:千萬(wàn)級(jí)、億級(jí)數(shù)據(jù),如何性能優(yōu)化? 教科書(shū)級(jí) 答案來(lái)了》 《峰值21WQps、億級(jí)DAU,小游戲《羊了個(gè)羊》是怎么架構(gòu)的?》 《100億級(jí)訂單怎么調(diào)度,來(lái)一個(gè)大廠的極品方案》 《2個(gè)大廠 100億級(jí) 超大流量 紅包 架構(gòu)方案》 … 更多架構(gòu)文章,正在添加中 實(shí)現(xiàn)你的 響應(yīng)式 自由:《響應(yīng)式圣經(jīng):10W字,實(shí)現(xiàn)Spring響應(yīng)式編程自由》 這是老版本 《Flux、Mono、Reactor 實(shí)戰(zhàn)(史上最全)》 實(shí)現(xiàn)你的 spring cloud 自由:《Spring cloud Alibaba 學(xué)習(xí)圣經(jīng)》 PDF 《分庫(kù)分表 Sharding-JDBC 底層原理、核心實(shí)戰(zhàn)(史上最全)》 《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之間混亂關(guān)系(史上最全)》 實(shí)現(xiàn)你的 linux 自由:《Linux命令大全:2W多字,一次實(shí)現(xiàn)Linux自由》 實(shí)現(xiàn)你的 網(wǎng)絡(luò) 自由:《TCP協(xié)議詳解 (史上最全)》 《網(wǎng)絡(luò)三張表:ARP表, MAC表, 路由表,實(shí)現(xiàn)你的網(wǎng)絡(luò)自由!!》 實(shí)現(xiàn)你的 分布式鎖 自由:《Redis分布式鎖(圖解 - 秒懂 - 史上最全)》 《Zookeeper 分布式鎖 - 圖解 - 秒懂》 實(shí)現(xiàn)你的 王者組件 自由:《隊(duì)列之王: Disruptor 原理、架構(gòu)、源碼 一文穿透》 《緩存之王:Caffeine 源碼、架構(gòu)、原理(史上最全,10W字 超級(jí)長(zhǎng)文)》 《緩存之王:Caffeine 的使用(史上最全)》 《Java Agent 探針、字節(jié)碼增強(qiáng) ByteBuddy(史上最全)》 實(shí)現(xiàn)你的 面試題 自由:4000頁(yè)《尼恩Java面試寶典 》 40個(gè)專題 |
今日新聞 |
推薦新聞 |
專題文章 |
CopyRight 2018-2019 實(shí)驗(yàn)室設(shè)備網(wǎng) 版權(quán)所有 |