<kbd id="9plqc"><label id="9plqc"></label></kbd>

        <th id="9plqc"></th>
        1. <center id="9plqc"><video id="9plqc"></video></center>
          <sub id="9plqc"><form id="9plqc"><pre id="9plqc"></pre></form></sub>
          <nav id="9plqc"><form id="9plqc"><legend id="9plqc"></legend></form></nav>
          100Wqps異地多活,得物是怎么架構(gòu)的? 您所在的位置:網(wǎng)站首頁(yè) 屬羊人生于正月好不好 100Wqps異地多活,得物是怎么架構(gòu)的?

          100Wqps異地多活,得物是怎么架構(gòu)的?

          2023-08-26 00:46| 來(lái)源: 網(wǎng)絡(luò)整理| 查看: 265

          說(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、數(shù)據(jù)同步延遲挑戰(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)的效果如下圖所示:

          得物APP機(jī)房改造

          得物多活改造一期目前有兩個(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方式。

          2.3.2 分布式ID

          單元化的庫(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)景去決定。

          2.5.1 定義消費(fèi)類型

          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)有做全單元化,而是半單元化

          3.1 整體方向

          首先要根據(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ù)。

          3.2.3 中心單元服務(wù)

          中心單元服務(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)景下處理流程。

          下發(fā)禁寫(xiě)規(guī)則

          當(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è)專題



          【本文地址】

          公司簡(jiǎn)介

          聯(lián)系我們

          今日新聞

          推薦新聞

          專題文章
            CopyRight 2018-2019 實(shí)驗(yàn)室設(shè)備網(wǎng) 版權(quán)所有
            黄色免费网站在线看,韩国精品在线观看,韩国美女一区二区,99国产热 罗定市| 手机| 江川县| 淳化县| 洞头县| 沧州市| 漳平市| 弥勒县| 宁陕县| 门头沟区| 济阳县| 上高县| 龙海市| 漳浦县| 乐亭县| 化德县| 乌什县| 酒泉市| 喜德县| 潼南县| 延津县| 宾阳县| 嘉祥县| 凌云县| 淮北市| 巴彦淖尔市| 绩溪县| 车险| 井研县| 滨州市| 涞水县| 宜宾县| 阿图什市| 南通市| 芒康县| 巢湖市| 资兴市| 顺义区| 上饶市| 广州市| 蒙自县| http://444 http://444 http://444 http://444 http://444 http://444