自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

萬(wàn)字長(zhǎng)文淺談三高系統(tǒng)建設(shè)方法論和實(shí)踐

開(kāi)發(fā) 前端
針對(duì)寫(xiě)多讀少的系統(tǒng),我們一般采用同步更新緩存,異步更新數(shù)據(jù)庫(kù),通過(guò)緩存來(lái)進(jìn)行抗寫(xiě)的流量,異步化更新數(shù)據(jù)庫(kù),通過(guò)緩存和異步化提高系統(tǒng)的性能;此種技術(shù)方案以緩存數(shù)據(jù)為主,數(shù)據(jù)庫(kù)數(shù)據(jù)為輔,這是我了解到的京東物流這邊大部分團(tuán)隊(duì)的技術(shù)方案,例如我們物流平臺(tái)-統(tǒng)一平臺(tái)小組的訂運(yùn)關(guān)系單據(jù)的存儲(chǔ)采用的就是這種技術(shù)方案。

1 概述

整個(gè)軟件的發(fā)展歷程是一部軟件復(fù)雜性對(duì)抗史,軟件的復(fù)雜性分為技術(shù)復(fù)雜性和業(yè)務(wù)復(fù)雜性,業(yè)務(wù)復(fù)雜性主要是建模和抽象設(shè)計(jì),技術(shù)復(fù)雜性主要是三高(高性能,高并發(fā),高可用)的應(yīng)對(duì),C端的業(yè)務(wù)一般以技術(shù)復(fù)雜性為主,業(yè)務(wù)復(fù)雜性為輔,而B(niǎo)端或者M(jìn)端的業(yè)務(wù)通常以業(yè)務(wù)復(fù)雜性為主,技術(shù)復(fù)雜性為輔。本篇文章主要是從后端研發(fā)的視角結(jié)合自己多年的B C端系統(tǒng)建設(shè)實(shí)踐談下三高系統(tǒng)的建設(shè)方法論和實(shí)踐,希望和大家相互交流,共同進(jìn)步,同時(shí)這是我參與創(chuàng)作者計(jì)劃的第1篇文章。

2 高性能篇

個(gè)人理解三高系統(tǒng)的核心在于高性能,系統(tǒng)的性能高,系統(tǒng)的處理速度快,吞吐量自然高,此時(shí)系統(tǒng)能夠應(yīng)對(duì)高并發(fā)的流量;系統(tǒng)的性能高,我們系統(tǒng)的對(duì)外承諾的TP99, TP999就比較低,超時(shí)等影響可用率的情況自然減少,系統(tǒng)的可用性也會(huì)提高,所以三高系統(tǒng)建設(shè)的出發(fā)點(diǎn)可以從系統(tǒng)的性能如何優(yōu)化進(jìn)行建設(shè),高性能篇從系統(tǒng)的讀寫(xiě)兩個(gè)維度談下系統(tǒng)的性能優(yōu)化方法論及實(shí)踐;

2.1 方法論

首先我們要清楚知道影響系統(tǒng)性能的因素有那些,通常有以下三方面的因素:計(jì)算(computation),通信(communication),存儲(chǔ)(storage)。計(jì)算層面:系統(tǒng)本身的計(jì)算邏輯復(fù)雜,F(xiàn)ullgc;通信層面:依賴(lài)的下游耗時(shí)比較高;存儲(chǔ)層面:大庫(kù)大表,慢sql,ES集群的數(shù)據(jù)節(jié)點(diǎn),索引,分片,分片大小設(shè)置的不合理;針對(duì)這些問(wèn)題,我們可以從讀寫(xiě)兩個(gè)維度針對(duì)性能問(wèn)題進(jìn)行優(yōu)化,下圖是我工作中解決性能問(wèn)題的一些方法。

圖片圖片

2.2 幾個(gè)實(shí)踐問(wèn)題的探討

2.2.1 讀優(yōu)化:緩存和數(shù)據(jù)庫(kù)的結(jié)合藝術(shù)

一想到高性能,我們首先想到的是使用緩存,無(wú)論是本地緩存還是分布式的緩存,通過(guò)實(shí)踐我們發(fā)現(xiàn)緩存確實(shí)是提高我們系統(tǒng)性能最有效的手段,雖然緩存能夠暫存部分?jǐn)?shù)據(jù),提高系統(tǒng)的性能,但是我們一般不會(huì)使用緩存持久化數(shù)據(jù),所以一般將緩存和數(shù)據(jù)庫(kù)結(jié)合使用,提高性能的同時(shí)也保證系統(tǒng)的可靠性;針對(duì)緩存和數(shù)據(jù)庫(kù)的結(jié)合使用,我們一般需要識(shí)別出系統(tǒng)是讀多寫(xiě)少的系統(tǒng),還是寫(xiě)多讀少的系統(tǒng);

2.2.1.1 讀多寫(xiě)少的系統(tǒng)

針對(duì)讀多寫(xiě)少的系統(tǒng),我們一般采用同步更新數(shù)據(jù)庫(kù),后刪除緩存;數(shù)據(jù)庫(kù)來(lái)應(yīng)對(duì)寫(xiě)的流量,緩存來(lái)應(yīng)對(duì)讀的流量,提高讀的性能;此種方案我們是以數(shù)據(jù)庫(kù)數(shù)據(jù)為主,緩存數(shù)據(jù)為輔,這是前司大部分團(tuán)隊(duì)采用的技術(shù)方案

圖片圖片

2.2.1.2 寫(xiě)多讀少的系統(tǒng)

針對(duì)寫(xiě)多讀少的系統(tǒng),我們一般采用同步更新緩存,異步更新數(shù)據(jù)庫(kù),通過(guò)緩存來(lái)進(jìn)行抗寫(xiě)的流量,異步化更新數(shù)據(jù)庫(kù),通過(guò)緩存和異步化提高系統(tǒng)的性能;此種技術(shù)方案以緩存數(shù)據(jù)為主,數(shù)據(jù)庫(kù)數(shù)據(jù)為輔,這是我了解到的京東物流這邊大部分團(tuán)隊(duì)的技術(shù)方案,例如我們物流平臺(tái)-統(tǒng)一平臺(tái)小組的訂運(yùn)關(guān)系單據(jù)的存儲(chǔ)采用的就是這種技術(shù)方案

圖片圖片

2.2.2 寫(xiě)優(yōu)化:秒殺場(chǎng)景下的異步化

針對(duì)于這種流量洪峰下的秒殺場(chǎng)景,對(duì)于接單接口的性能是很大的考驗(yàn),所以接單接口不會(huì)有很多同步交互的復(fù)雜邏輯。我們一般都是先異步將訂單接下來(lái),返回給用戶(hù)成功,通過(guò)消息隊(duì)列來(lái)削峰處理訂單,緩存存儲(chǔ)相關(guān)sku的庫(kù)存,當(dāng)扣減庫(kù)存成功后,再短信通知用戶(hù)支付訂單。

圖片圖片

3 高并發(fā)篇

提到高并發(fā)我們想到的是高吞吐,流量洪峰;如何提高高并發(fā)我們可以從單機(jī)的性能優(yōu)化,和集群的擴(kuò)展來(lái)進(jìn)行提高我們系統(tǒng)的并發(fā)能力,其實(shí)系統(tǒng)的高性能直接就提高了系統(tǒng)的高并發(fā),上面的高性能篇主要是從單機(jī)的維度提高處理的速度來(lái)提高單機(jī)的并發(fā)處理能力,本章主要從集群的維度通過(guò)擴(kuò)展:水平擴(kuò)展,縱向擴(kuò)展,垂直擴(kuò)展三維立體來(lái)提高系統(tǒng)的并發(fā)能力。

3.1 方法論

圖片圖片

3.1.1 X軸:水平擴(kuò)展

水平擴(kuò)展就是擴(kuò)容,是我們采用最多的抗并發(fā)的措施:加機(jī)器,擴(kuò)分片,每年618,雙11大促時(shí),這是我們的常規(guī)操作,現(xiàn)有分組下的機(jī)器處理能力有限,我們通過(guò)擴(kuò)容來(lái)應(yīng)對(duì)大促的流量,擴(kuò)容我們分為應(yīng)用層和存儲(chǔ)層,應(yīng)用層都是無(wú)狀態(tài)的服務(wù),我們可以通過(guò)公司部署平臺(tái)行云快速的擴(kuò)容增加機(jī)器,存儲(chǔ)層的擴(kuò)容相對(duì)比較麻煩,新增分片后,還涉及到數(shù)據(jù)的遷移以及分片規(guī)則的調(diào)整。

圖片圖片

3.1.2 Y軸:縱向擴(kuò)展

整個(gè)軟件應(yīng)用的架構(gòu)經(jīng)歷單體應(yīng)用,SOA,微服務(wù),服務(wù)網(wǎng)格的演進(jìn)。早期的架構(gòu)風(fēng)格所有的服務(wù)功能都融合在單體應(yīng)用中,通過(guò)單體服務(wù)來(lái)抗所有的流量,后來(lái)隨著業(yè)務(wù)的復(fù)雜性和用戶(hù)的增多以及我們基于對(duì)業(yè)務(wù)的深入理解采用DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))來(lái)指導(dǎo)我們按照領(lǐng)域劃分服務(wù),進(jìn)行微服務(wù)建設(shè),下圖是一個(gè)電商的單體應(yīng)用到按照DDD進(jìn)行微服務(wù)劃分的一個(gè)演進(jìn)過(guò)程。

圖片圖片

3.1.3 Z軸:垂直擴(kuò)展

當(dāng)我們?cè)趹?yīng)用層進(jìn)行水平擴(kuò)展時(shí),每增加一臺(tái)機(jī)器都會(huì)增加數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)鏈接,數(shù)據(jù)庫(kù)的連接數(shù)屬于寶貴資源,達(dá)到上限后,應(yīng)用層再擴(kuò)容就會(huì)出現(xiàn)連接數(shù)耗盡的異常,此時(shí)存儲(chǔ)層成了整個(gè)系統(tǒng)高并發(fā)的瓶頸,針對(duì)數(shù)據(jù)庫(kù)我們一般采用分片(分而治之)的思想:分庫(kù)分表,通過(guò)增加庫(kù)實(shí)例來(lái)增加訪(fǎng)問(wèn)的連接數(shù),下圖是訂單進(jìn)行分庫(kù)分表的架構(gòu)。

圖片圖片

集群中數(shù)據(jù)庫(kù)的主從庫(kù)數(shù)量是有限制的的,達(dá)到最大限制后,一個(gè)機(jī)房的數(shù)據(jù)庫(kù)集群成了系統(tǒng)的瓶頸,解決方案是進(jìn)行單元化建設(shè),系統(tǒng)的流量和數(shù)據(jù)閉環(huán)在一個(gè)單元,這個(gè)單元分布在全國(guó)甚至全世界不同的地域,而不是集中在某個(gè)機(jī)房某個(gè)地域,北京的系統(tǒng)單元為北京用戶(hù)提供服務(wù),上海的系統(tǒng)單元為上海用戶(hù)提供服務(wù),就類(lèi)似于京東物流的倉(cāng)庫(kù)一樣,建在離用戶(hù)最近的地方,北京倉(cāng)服務(wù)北京用戶(hù),上海倉(cāng)服務(wù)上海用戶(hù)。大家可以看到系統(tǒng)的建設(shè)和業(yè)務(wù)的發(fā)展底層的思想都是統(tǒng)一的,中國(guó)的頭部互聯(lián)網(wǎng)還都是業(yè)務(wù)驅(qū)動(dòng),所以技術(shù)要服務(wù)好業(yè)務(wù)??傊覀兛梢钥吹酵ㄟ^(guò)分庫(kù)分表和單元化這種垂直擴(kuò)展提高并發(fā)的同時(shí)也增強(qiáng)了系統(tǒng)的可用性,下圖是我們進(jìn)行單元化建設(shè)的過(guò)程。

圖片圖片

3.2 幾個(gè)實(shí)踐問(wèn)題的探討

3.2.1 DDD在零售物流平臺(tái)的實(shí)踐

縱向的擴(kuò)展,我們采用DDD進(jìn)行領(lǐng)域的劃分進(jìn)行微服務(wù)的建設(shè),DDD的實(shí)踐必須基于對(duì)業(yè)務(wù)的深入理解,所以作為技術(shù)人員,如果想將DDD很好的落地,必須和業(yè)務(wù)專(zhuān)家,產(chǎn)品一起頭腦風(fēng)暴,技術(shù)前置去了解業(yè)務(wù)。研發(fā)可以從業(yè)務(wù)流程上去了解業(yè)務(wù),然后基于業(yè)務(wù)流程進(jìn)行領(lǐng)域劃分;

3.2.1.1 業(yè)務(wù)流程

正向流程:從B端商家視角來(lái)看,商家選擇服務(wù)商品比如卓配產(chǎn)品后,進(jìn)行下單,服務(wù)商進(jìn)行接單,分配快遞員,快遞員上門(mén)取件,對(duì)用戶(hù)郵寄的貨品進(jìn)行稱(chēng)重量方,詢(xún)價(jià)計(jì)費(fèi),然后商家支付運(yùn)費(fèi),快遞員完成攬收,進(jìn)入履約層面:貨品進(jìn)行運(yùn)輸,配送,直至C端用戶(hù)簽收完成妥投。

圖片圖片

逆向流程:從C端用戶(hù)視角來(lái)看,用戶(hù)需要申請(qǐng)售后退貨,待商家審核通過(guò)后,選擇相應(yīng)的商品服務(wù)進(jìn)行下單,后續(xù)的流程和正向流程類(lèi)似。

圖片圖片

3.2.1.2 應(yīng)用領(lǐng)域劃分

應(yīng)用領(lǐng)域的劃分主要根據(jù)我們的業(yè)務(wù)流程介紹提供了那些功能;目前我們系統(tǒng)支撐的業(yè)務(wù)來(lái)源包括:零售的商家后臺(tái)(京麥),訂單中臺(tái),售后,傳美,快遞鳥(niǎo),中鐵,統(tǒng)一發(fā)貨平臺(tái)等等;

從需求側(cè)來(lái)看,我們的上游包括了京東物流,京東零售,京東工業(yè),外部的ISV等給物流平臺(tái)下單;

從供給側(cè)來(lái)看,我們的服務(wù)商包括:京東快遞,快運(yùn),中通,圓通,韻達(dá)等來(lái)提供履約的能力;

從領(lǐng)域劃分角度來(lái)看,將領(lǐng)域劃分為:商品服務(wù)域,訂單域,支付結(jié)算域,履約域,每個(gè)領(lǐng)域包括了提供的功能如下圖;至于為啥這樣劃分,我的思考是這樣的,相較于C端零售側(cè)的電商交易,我們是服務(wù)于商家的B端物流側(cè)的物流交易;C端零售針對(duì)于用戶(hù)提供的是實(shí)物的商品:手機(jī),電腦;B端物流針對(duì)于商家提供的是虛擬的商品:一種履約物流服務(wù),將貨品從商家交付到用戶(hù);所以無(wú)論是我們的卓配產(chǎn)品還是電子面單產(chǎn)品,我們?yōu)樯虘?hù)提供了這些虛擬商品,商家選擇這些虛擬商品后,就可以下單,取消,改單,支付,服務(wù)商進(jìn)行履約;

圖片圖片

3.2.2 熱key處理

垂直的擴(kuò)展,在百億補(bǔ)貼,大促,秒殺場(chǎng)景下,相關(guān)sku會(huì)成為訪(fǎng)問(wèn)的熱點(diǎn),如果將相關(guān)sku存儲(chǔ)到某個(gè)單一的分片則可能出現(xiàn)流量訪(fǎng)問(wèn)傾斜的問(wèn)題,某個(gè)分片會(huì)承擔(dān)大部分的流量出現(xiàn)性能變差甚至分片被打垮的情況;針對(duì)熱key的問(wèn)題我們可以采用如下兩種解決方案:

本地緩存:在應(yīng)用層增加本地緩存;先查本地緩存,本地緩存沒(méi)有查詢(xún)分布式緩存,分布式緩存沒(méi)有查詢(xún)數(shù)據(jù)庫(kù);

隨機(jī)數(shù)法:針對(duì)某個(gè)key,我們可以在這個(gè)key后面增加一個(gè)隨機(jī)數(shù),比如增加兩位的隨機(jī),就可以將該key分散到100個(gè)分片上,避免熱點(diǎn)分片

總之無(wú)論是本地緩存還是key+隨機(jī)數(shù),都是將熱key分散到不同的節(jié)點(diǎn)上來(lái)分散流量,提高并發(fā)的同時(shí),也避免流量?jī)A斜,將某個(gè)節(jié)點(diǎn)打垮;

4 高可用篇

保證系統(tǒng)的可用性是系統(tǒng)建設(shè)中的重中之重,如果沒(méi)有可用性,高性能和高并發(fā)也無(wú)從談起,高可用的建設(shè)通常是通過(guò)保護(hù)系統(tǒng)和冗余的方法來(lái)進(jìn)行容錯(cuò)保證系統(tǒng)的可用性。本篇主要從三個(gè)維度:應(yīng)用層,存儲(chǔ)層,部署層談下可用性的建設(shè)。應(yīng)用層的內(nèi)容來(lái)自我的另一篇文章:http://sd.jd.com/article/33612?shareId=224276&isHideShareButtnotallow=1

4.1 方法論

圖片圖片

4.1.1 應(yīng)用層

4.1.1.1 限流

限流一般是從服務(wù)提供者provider的視角提供的針對(duì)自我保護(hù)的能力,對(duì)于流量負(fù)載超過(guò)我們系統(tǒng)的處理能力,限流策略可以防止我們的系統(tǒng)被激增的流量打垮。京東內(nèi)部無(wú)論是同步交互的JSF, 還是異步交互的JMQ都提供了限流的能力,大家可以根據(jù)自己系統(tǒng)的情況進(jìn)行設(shè)置;我們知道常見(jiàn)的限流算法包括:計(jì)數(shù)器算法,滑動(dòng)時(shí)間窗口算法,漏斗算法,令牌桶算法,具體算法可以網(wǎng)上google下,下面是這些算法的優(yōu)缺點(diǎn)對(duì)比。

算法

優(yōu)點(diǎn)

缺點(diǎn)

流量計(jì)數(shù)器算法

簡(jiǎn)單好理解

單位時(shí)間很難把控,不平滑

滑動(dòng)時(shí)間窗口算法

時(shí)間好把控

1 超過(guò)窗口時(shí)間的流量就丟棄或降級(jí)2 沒(méi)有辦法削峰填谷

漏桶算法

削峰填谷

1 漏桶大小的控制,太大給服務(wù)端造成壓力,太小大量請(qǐng)求被丟棄2 漏桶給下游發(fā)送請(qǐng)求的速率固定

令牌桶算法

1 削峰填谷2 動(dòng)態(tài)控制令牌桶的大小,從而控制向下游發(fā)送請(qǐng)求的速率

1 實(shí)現(xiàn)相對(duì)復(fù)雜2 只能預(yù)先設(shè)計(jì)不適配突發(fā)

4.1.1.2 熔斷降級(jí)

熔斷和降級(jí)是兩件事情,但是他們一般是結(jié)合在一起使用的。熔斷是防止我們的系統(tǒng)被下游系統(tǒng)拖垮,比如下游系統(tǒng)接口性能?chē)?yán)重變差,甚至下游系統(tǒng)掛了;這個(gè)時(shí)候會(huì)導(dǎo)致大量的線(xiàn)程堆積,不能釋放占用的CPU,內(nèi)存等資源,這種情況下不僅影響該接口的性能,還會(huì)影響其他接口的性能,嚴(yán)重的情況會(huì)將我們的系統(tǒng)拖垮,造成雪崩效應(yīng),通過(guò)打開(kāi)熔斷器,流量不再請(qǐng)求到有問(wèn)題的系統(tǒng),可以保護(hù)我們的系統(tǒng)不被拖垮。降級(jí)是一種有損操作,我們作為服務(wù)提供者,需要將這種損失盡可能降到最低,無(wú)論是返回友好的提示,還是返回可接受的降級(jí)數(shù)據(jù)。降級(jí)細(xì)分的話(huà)又分為人工降級(jí),自動(dòng)降級(jí)。

人工降級(jí):人工降級(jí)一般采用降級(jí)開(kāi)關(guān)來(lái)控制,公司內(nèi)部一般采用配置中心Ducc來(lái)做開(kāi)關(guān)降級(jí),開(kāi)關(guān)的修改也是線(xiàn)上操作,這塊也需要做好監(jiān)控

自動(dòng)降級(jí):自動(dòng)降級(jí)是采用自動(dòng)化的中間件例如Hystrix,公司的小盾龍等;如果采用自動(dòng)降級(jí)的話(huà);我們必須要對(duì)降級(jí)的條件非常的明確,比如失敗的調(diào)用次數(shù)等;

4.1.1.3 超時(shí)設(shè)置

分布式系統(tǒng)中的難點(diǎn)之一:不可靠的網(wǎng)絡(luò),京東物流現(xiàn)有的微服務(wù)架構(gòu)下,服務(wù)之間都是通過(guò)JSF網(wǎng)絡(luò)交互進(jìn)行同步通信,我們探測(cè)下游依賴(lài)服務(wù)是否可用的最快捷的方式是設(shè)置超時(shí)時(shí)間。超時(shí)的設(shè)置可以讓系統(tǒng)快速失敗,進(jìn)行自我保護(hù),避免無(wú)限等待下游依賴(lài)系統(tǒng),將系統(tǒng)的線(xiàn)程耗盡,系統(tǒng)拖垮;

超時(shí)時(shí)間如何設(shè)置也是一門(mén)學(xué)問(wèn),如何設(shè)置一個(gè)合理的超時(shí)時(shí)間也是一個(gè)逐步迭代的過(guò)程,比如下游新開(kāi)發(fā)的接口,一般會(huì)基于壓測(cè)提供一個(gè)TP99的耗時(shí),我們會(huì)基于此配置超時(shí)時(shí)間;老接口的話(huà),會(huì)基于線(xiàn)上的TP99耗時(shí)來(lái)配置超時(shí)時(shí)間。

超時(shí)時(shí)間在設(shè)置的時(shí)候需要遵循漏斗原則,從上游系統(tǒng)到下游系統(tǒng)設(shè)置的超時(shí)時(shí)間要逐漸減少,如下圖所示。為什么要滿(mǎn)足漏斗原則,假設(shè)不滿(mǎn)足漏斗原則,比如服務(wù)A調(diào)取服務(wù)B的超時(shí)時(shí)間設(shè)置成500ms,而服務(wù)B調(diào)取服務(wù)C的超時(shí)時(shí)間設(shè)置成800ms,這個(gè)時(shí)候回導(dǎo)致服務(wù)A調(diào)取服務(wù)B大量的超時(shí)從而導(dǎo)致可用率降低,而此時(shí)服務(wù)B從自身角度看是可用的;

圖片圖片

4.1.1.4 重試

分布式系統(tǒng)中性能的影響主要是通信,無(wú)論是在分布式系統(tǒng)中還是垮團(tuán)隊(duì)溝通,communication是最昂貴的;比如我們研發(fā)都知道需求的交付有一半以上甚至更多的時(shí)間花在跨團(tuán)隊(duì)的溝通上,真正寫(xiě)代碼的時(shí)間是很少的;分布式系統(tǒng)中我們查看調(diào)用鏈路,其實(shí)我們系統(tǒng)本身計(jì)算的耗時(shí)是很少的,主要來(lái)自于外部系統(tǒng)的網(wǎng)絡(luò)交互,無(wú)論是下游的業(yè)務(wù)系統(tǒng),還是中間件:Mysql, redis, es等等;所以在和外部系統(tǒng)的一次請(qǐng)求交互中,我們系統(tǒng)是希望盡最大努力得到想要的結(jié)果,但往往事與愿違,由于不可靠網(wǎng)絡(luò)的原因,我們?cè)诤拖掠蜗到y(tǒng)交互時(shí),都會(huì)配置超時(shí)重試次數(shù),希望在可接受的SLA范圍內(nèi)一次請(qǐng)求拿到結(jié)果,但重試不是無(wú)限的重試,我們一般都是配置重試次數(shù)的限制,偶爾抖動(dòng)的重試可以提高我們系統(tǒng)的可用率,如果下游服務(wù)故障掛掉,重試反而會(huì)增加下游系統(tǒng)的負(fù)載,從而增加故障的嚴(yán)重程度。在一次請(qǐng)求調(diào)用中,我們要知道對(duì)外提供的API,后面是有多少個(gè)service在提供服務(wù),如果調(diào)用鏈路比較長(zhǎng),服務(wù)之間rpc交互都設(shè)置了重試次數(shù),這個(gè)時(shí)候我們需要警惕重試風(fēng)暴。如下圖service D 出現(xiàn)問(wèn)題,重試風(fēng)暴會(huì)加重service D的故障嚴(yán)重程度。對(duì)于API的重試,我們還要區(qū)分該接口是讀接口還是寫(xiě)接口,如果是讀接口重試一般沒(méi)什么影響,寫(xiě)接口重試一定要做好接口的冪等性。

圖片圖片

4.1.1.5 隔離

隔離是將故障爆炸半徑最小化的有效手段,我們通過(guò)不同層面的隔離來(lái)控制影響范圍,保證系統(tǒng)的高可用:

4.1.1.5.1 系統(tǒng)建設(shè)層面隔離

我們知道系統(tǒng)的分類(lèi)可以分為:在線(xiàn)的系統(tǒng),離線(xiàn)系統(tǒng)(批處理系統(tǒng)),近實(shí)時(shí)系統(tǒng)(流處理系統(tǒng)),如下是這些系統(tǒng)的定義:

在線(xiàn)系統(tǒng):服務(wù)端等待請(qǐng)求的到達(dá),接收到請(qǐng)求后,服務(wù)盡可能快的處理,然后返回給客戶(hù)端一個(gè)響應(yīng),響應(yīng)時(shí)間通常是在線(xiàn)服務(wù)性能的主要衡量指標(biāo)。我們生活中在手機(jī)使用的APP大部分都是在線(xiàn)系統(tǒng);

離線(xiàn)系統(tǒng):或稱(chēng)批處理系統(tǒng),接收大量的輸入數(shù)據(jù),運(yùn)行一個(gè)作業(yè)來(lái)處理數(shù)據(jù),并產(chǎn)出輸出數(shù)據(jù),作業(yè)往往需要定時(shí),定期運(yùn)行一段時(shí)間,比如從幾分鐘到幾天,所以用戶(hù)通常不會(huì)等待作業(yè)完成,吞吐量是離線(xiàn)系統(tǒng)的主要衡量指標(biāo)。例如我們看到的報(bào)表數(shù)據(jù):日訂單量,月訂單量,日活躍用戶(hù)數(shù),月活躍用戶(hù)數(shù)都是批處理系統(tǒng)運(yùn)算一段時(shí)間得到的;

近實(shí)時(shí)系統(tǒng):或者稱(chēng)流處理系統(tǒng),其介于在線(xiàn)系統(tǒng)和離線(xiàn)系統(tǒng)之間,流處理系統(tǒng)一般會(huì)有觸發(fā)源:用戶(hù)的行為操作,數(shù)據(jù)庫(kù)的寫(xiě)操作,傳感器等,觸發(fā)源作為消息會(huì)通過(guò)消息代理中間件:JMQ, KAFKA等進(jìn)行傳遞,消費(fèi)者消費(fèi)到消息后再做其他的操作,例如構(gòu)建緩存,索引,通知用戶(hù)等;

以上三種系統(tǒng)是需要進(jìn)行隔離建設(shè)的,因?yàn)樗麄兊暮饬恐笜?biāo)及對(duì)資源的使用情況完全不一樣的,比如我們小組會(huì)將在線(xiàn)系統(tǒng)作為一個(gè)服務(wù)單獨(dú)部署:jdl-uep-main, 離線(xiàn)系統(tǒng)和近實(shí)時(shí)系統(tǒng)作為一個(gè)服務(wù)單獨(dú)部署:jdl-uep-worker;

4.1.1.5.2 環(huán)境的隔離

從研發(fā)到上線(xiàn)階段我們會(huì)使用不同的環(huán)境,比如業(yè)界常見(jiàn)的環(huán)境分為:開(kāi)發(fā),測(cè)試,預(yù)發(fā)和線(xiàn)上環(huán)境;研發(fā)人員在開(kāi)發(fā)環(huán)境進(jìn)行開(kāi)發(fā)和聯(lián)調(diào),測(cè)試人員在測(cè)試環(huán)境進(jìn)行測(cè)試,運(yùn)營(yíng)和產(chǎn)品在預(yù)發(fā)環(huán)境進(jìn)行UAT,最終交付的產(chǎn)品部署到線(xiàn)上環(huán)境提供給用戶(hù)使用。在研發(fā)流程中,我們部署時(shí)要遵循從應(yīng)用層到中間件層再到存儲(chǔ)層,都要在一個(gè)環(huán)境,嚴(yán)禁垮環(huán)境的調(diào)用,比如測(cè)試環(huán)境調(diào)用線(xiàn)上,預(yù)發(fā)環(huán)境調(diào)用線(xiàn)上等。

圖片圖片

4.1.1.5.3 數(shù)據(jù)隔離

隨著業(yè)務(wù)的發(fā)展,我們對(duì)外提供的服務(wù)往往會(huì)支撐多業(yè)務(wù),多租戶(hù),所以這個(gè)時(shí)候我們會(huì)按照業(yè)務(wù)進(jìn)行數(shù)據(jù)隔離;比如我們組產(chǎn)生的物流訂單數(shù)據(jù)業(yè)務(wù)方就包含京東零售,其他電商平臺(tái),ISV等,為了避免彼此的影響我們需要在存儲(chǔ)層對(duì)數(shù)據(jù)進(jìn)行隔離,數(shù)據(jù)的隔離可以按照不同粒度,第一種是通過(guò)租戶(hù)id字段進(jìn)行區(qū)分,所有的數(shù)據(jù)存儲(chǔ)在一張表中,另外一個(gè)是庫(kù)粒度的區(qū)分,不同的租戶(hù)單獨(dú)分配對(duì)應(yīng)的數(shù)據(jù)庫(kù)。

圖片圖片

圖片圖片

數(shù)據(jù)的隔離除了按照業(yè)務(wù)進(jìn)行隔離外,還有按照環(huán)境進(jìn)行隔離的,比如我們的數(shù)據(jù)庫(kù)分為測(cè)試庫(kù),預(yù)發(fā)庫(kù),線(xiàn)上庫(kù),全鏈路壓測(cè)時(shí),我們?yōu)榱四M線(xiàn)上的環(huán)境,同時(shí)避免污染線(xiàn)上的數(shù)據(jù),往往會(huì)創(chuàng)建影子庫(kù),影子表等。根據(jù)數(shù)據(jù)的訪(fǎng)問(wèn)頻次進(jìn)行隔離,我們將經(jīng)常訪(fǎng)問(wèn)的數(shù)據(jù)稱(chēng)為熱數(shù)據(jù),不經(jīng)常訪(fǎng)問(wèn)的數(shù)據(jù)稱(chēng)為冷數(shù)據(jù);將經(jīng)常訪(fǎng)問(wèn)的數(shù)據(jù)緩存到緩存,提高系統(tǒng)的性能。不經(jīng)常訪(fǎng)問(wèn)的數(shù)據(jù)持久化到數(shù)據(jù)庫(kù)或者將不使用的數(shù)據(jù)結(jié)轉(zhuǎn)歸檔到OSS,避免大庫(kù)大表。

4.1.1.5.4 核心/非核心流程隔離

我們知道應(yīng)用是分級(jí)的,京東內(nèi)部針對(duì)應(yīng)用的重要程度會(huì)將應(yīng)用分為0,1,2,3級(jí)應(yīng)用。業(yè)務(wù)的流程也分為黃金流程和非黃金流程。在業(yè)務(wù)流程中,針對(duì)不同級(jí)別的應(yīng)用交互,需要將核心和非核心的流程進(jìn)行隔離。例如在交易業(yè)務(wù)過(guò)程中,會(huì)涉及到訂單系統(tǒng),支付系統(tǒng),通知系統(tǒng),那這個(gè)過(guò)程中核心系統(tǒng)是訂單系統(tǒng)和支付系統(tǒng),而通知相對(duì)來(lái)說(shuō)重要性不是那么高,所以我們會(huì)投入更多的資源到訂單系統(tǒng)和支付系統(tǒng),優(yōu)先保證這兩個(gè)系統(tǒng)的穩(wěn)定性,通知系統(tǒng)可以采用異步的方式與其他兩個(gè)系統(tǒng)解耦隔離,避免對(duì)其他另外兩個(gè)系統(tǒng)的影響。

圖片圖片

4.1.1.5.5 讀寫(xiě)隔離

應(yīng)用層面,領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)中最著名的CQRS(Command Query Responsibility Segregation)將寫(xiě)服務(wù)和讀服務(wù)進(jìn)行隔離。寫(xiě)服務(wù)主要處理來(lái)自客戶(hù)端的command寫(xiě)命令,而讀服務(wù)處理來(lái)自客戶(hù)端的query讀請(qǐng)求,這樣從應(yīng)用層面進(jìn)行讀寫(xiě)隔離,不僅可以提高系統(tǒng)的可擴(kuò)展性,同時(shí)也會(huì)提高系統(tǒng)的可維護(hù)性,應(yīng)用層面我們都采用微服務(wù)架構(gòu),應(yīng)用層都是無(wú)狀態(tài)服務(wù),可以擴(kuò)容加機(jī)器隨意擴(kuò)展,存儲(chǔ)層需要持久化,擴(kuò)展就比較費(fèi)勁。除了應(yīng)用層面的CQRS,在存儲(chǔ)層面,我們也會(huì)進(jìn)行讀寫(xiě)隔離,例如數(shù)據(jù)庫(kù)都會(huì)采用一主多從的架構(gòu),讀請(qǐng)求可以路由到從庫(kù)從而分擔(dān)主庫(kù)的壓力,提高系統(tǒng)的性能和吞吐量。所以應(yīng)用層面通過(guò)讀寫(xiě)隔離主要解決可擴(kuò)展問(wèn)題,存儲(chǔ)層面主要解決性能和吞吐量的問(wèn)題。

圖片圖片

4.1.1.5.6 線(xiàn)程池隔離

線(xiàn)程是昂貴的資源,為了提高線(xiàn)程的使用效率,復(fù)用線(xiàn)程,避免創(chuàng)建和銷(xiāo)毀的消耗,我們采用了池化技術(shù),線(xiàn)程池,但是在使用線(xiàn)程的過(guò)程中,我們也做好線(xiàn)程池的隔離,避免多個(gè)API接口復(fù)用同一個(gè)線(xiàn)程。

圖片圖片

4.1.1.6 兼容

我們?cè)趯?duì)老系統(tǒng),老功能進(jìn)行重構(gòu)迭代的時(shí)候,一定要做好兼容,否則上線(xiàn)后會(huì)出現(xiàn)重大的線(xiàn)上問(wèn)題,公司內(nèi)外有大量因?yàn)闆](méi)有做好兼容性,而導(dǎo)致資損的情況。兼容分為:向前兼容性和向后兼容性,需要好好的區(qū)分他們,如下是他們的定義:

向前兼容性:向前兼容性指的是舊版本的軟件或硬件能夠與將來(lái)推出的新版本兼容的特性,簡(jiǎn)而言之舊版本軟件或系統(tǒng)兼容新的數(shù)據(jù)和流量。

向后兼容性:向后兼容性則是指新版本的軟件或硬件能夠與之前版本的系統(tǒng)或組件兼容的特性,簡(jiǎn)而言之新版本軟件或系統(tǒng)兼容老的數(shù)據(jù)和流量。

根據(jù)新老系統(tǒng)和新老數(shù)據(jù)我們可以將系統(tǒng)劃分為四個(gè)象限:第一象限:新系統(tǒng)和新數(shù)據(jù)是我們系統(tǒng)改造上線(xiàn)后的狀態(tài),第三象限:老系統(tǒng)和老數(shù)據(jù)是我們系統(tǒng)改造上線(xiàn)前的狀態(tài),第一象限和第三象限的問(wèn)題我們?cè)谘邪l(fā)和測(cè)試階段一般都能發(fā)現(xiàn)排除掉,線(xiàn)上故障的高發(fā)期往往出現(xiàn)在第二和第四象限,第二象限是因?yàn)闆](méi)有做好向前兼容性,例如上線(xiàn)過(guò)程中,發(fā)現(xiàn)問(wèn)題進(jìn)行了代碼回滾,但是在上線(xiàn)過(guò)程中產(chǎn)生了新數(shù)據(jù),回滾后的老系統(tǒng)不能處理上線(xiàn)過(guò)程中新產(chǎn)生的數(shù)據(jù),導(dǎo)致線(xiàn)上故障。第四象限是因?yàn)闆](méi)有做好向后兼容性,上線(xiàn)后新系統(tǒng)影響了老流程。針對(duì)第二象限的問(wèn)題,我們可以構(gòu)造新的數(shù)據(jù)去驗(yàn)證老的系統(tǒng),針對(duì)第四象限的問(wèn)題,我們可以通過(guò)流量的錄制回放解決,錄制線(xiàn)上的老流量,對(duì)新功能進(jìn)行驗(yàn)證。

圖片圖片

4.1.2 存儲(chǔ)層

存儲(chǔ)層主要通過(guò)復(fù)制和分片來(lái)保證存儲(chǔ)層的高可用,復(fù)制主要是通過(guò)副本(主從節(jié)點(diǎn),主從副本)來(lái)保證高可用,分片是將數(shù)據(jù)分散到不同的節(jié)點(diǎn)上來(lái)保證高可用(雞蛋不要放在同一個(gè)籃子中)。復(fù)制和分片在保證高可用的情況下,其實(shí)也提高了系統(tǒng)的高性能和高并發(fā),復(fù)制和分片的思想在Mysql,Redis,ElasticSearch, kafka中都進(jìn)行了采用。

4.1.2.1 復(fù)制

復(fù)制技術(shù)是一份數(shù)據(jù)的完整的拷貝,思想是通過(guò)冗余保證高可用。復(fù)制又可以分為:主從復(fù)制,多主復(fù)制,無(wú)主復(fù)制。

主從復(fù)制:客戶(hù)端將所有寫(xiě)入操作發(fā)送到單個(gè)節(jié)點(diǎn)(主庫(kù)),該節(jié)點(diǎn)將數(shù)據(jù)更改事件流發(fā)送到其他副本(從庫(kù))。讀取可以在任何副本上執(zhí)行,但從庫(kù)的讀取結(jié)果可能是陳舊的。

多主復(fù)制:客戶(hù)端將每個(gè)寫(xiě)入發(fā)送到幾個(gè)主庫(kù)節(jié)點(diǎn)之一,其中任何一個(gè)主庫(kù)都可以接受寫(xiě)入。主庫(kù)將數(shù)據(jù)更改事件流發(fā)送給彼此以及任何從庫(kù)節(jié)點(diǎn)。

無(wú)主復(fù)制:客戶(hù)端將每個(gè)寫(xiě)入發(fā)送到幾個(gè)節(jié)點(diǎn),并從多個(gè)節(jié)點(diǎn)并行讀取,以檢測(cè)和糾正具有陳舊數(shù)據(jù)的節(jié)點(diǎn)。

4.1.2.2 分區(qū)

分區(qū)也稱(chēng)為分片,對(duì)于非常大的數(shù)據(jù)集在單節(jié)點(diǎn)進(jìn)行存儲(chǔ)時(shí),一方面可用性比較低(雞蛋放在同一個(gè)籃子中),另一方面也會(huì)遇到存儲(chǔ)和性能的瓶頸,我們需要將大的數(shù)據(jù)集通過(guò)負(fù)載均衡分片到不同的節(jié)點(diǎn)上,每條數(shù)據(jù)(每條記錄,每行或每個(gè)文檔)屬于且僅屬于一個(gè)分區(qū),每個(gè)分區(qū)都是自己的小型數(shù)據(jù)庫(kù)。分區(qū)我們分為鍵范圍分區(qū),散列分區(qū)。

鍵范圍分區(qū):其中鍵是有序的,并且分區(qū)擁有從某個(gè)最小值到某個(gè)最大值的所有鍵。排序的優(yōu)勢(shì)在于可以進(jìn)行有效的范圍查詢(xún),但是如果應(yīng)用程序經(jīng)常訪(fǎng)問(wèn)相鄰的鍵,則存在熱點(diǎn)的風(fēng)險(xiǎn)。在這種方法中,當(dāng)分區(qū)變得太大時(shí),通常將分區(qū)分成兩個(gè)子分區(qū)來(lái)動(dòng)態(tài)地重新平衡分區(qū)。

散列分區(qū):散列函數(shù)應(yīng)用于每個(gè)鍵,分區(qū)擁有一定范圍的散列。這種方法破壞了鍵的排序,使得范圍查詢(xún)效率低下,但可以更均勻地分配負(fù)載。通過(guò)散列進(jìn)行分區(qū)時(shí),通常先提前創(chuàng)建固定數(shù)量的分區(qū),為每個(gè)節(jié)點(diǎn)分配多個(gè)分區(qū),并在添加或刪除節(jié)點(diǎn)時(shí)將整個(gè)分區(qū)從一個(gè)節(jié)點(diǎn)移動(dòng)到另一個(gè)節(jié)點(diǎn)。也可以使用動(dòng)態(tài)分區(qū)。

4.1.2.3 Redis 的復(fù)制和分片

redis cluster集群中,我們會(huì)劃分16384個(gè)槽,key 通過(guò)散列哈希算法會(huì)映射到相應(yīng)的槽中,這些槽分配到不同的分片上,每個(gè)分片有主節(jié)點(diǎn)和從節(jié)點(diǎn),主節(jié)點(diǎn)對(duì)外提供讀寫(xiě)服務(wù),從節(jié)點(diǎn)對(duì)外提供讀服務(wù)。當(dāng)某個(gè)分片的主節(jié)點(diǎn)掛掉,其他分片的主節(jié)點(diǎn)會(huì)從掛掉分片的從節(jié)點(diǎn)選擇一個(gè)作為主節(jié)點(diǎn)繼續(xù)對(duì)外提供服務(wù)。整體的架構(gòu)如下圖所示

圖片圖片

4.1.2.4 ES索引的復(fù)制和分片

我們?cè)趧?chuàng)建ES索引時(shí),會(huì)指定分片的數(shù)量和副本的數(shù)量,分片的數(shù)量確定后是不允許修改的,副本的數(shù)量允許修改,分片的數(shù)量一般和數(shù)據(jù)節(jié)點(diǎn)的數(shù)量保持一致,這樣能將索引的數(shù)據(jù)分配到每個(gè)數(shù)據(jù)節(jié)點(diǎn)上,每個(gè)數(shù)據(jù)節(jié)點(diǎn)都存儲(chǔ)索引的部分?jǐn)?shù)據(jù),Primary分片可以對(duì)外提供讀寫(xiě)服務(wù),Replica分片對(duì)外提供讀服務(wù)的同時(shí)作為備份節(jié)點(diǎn)保證可用性,ES索引的不同分片在不同數(shù)據(jù)節(jié)點(diǎn)的分布如下圖所示。

圖片圖片

4.1.2.5 Kafka topic的復(fù)制和分區(qū)

kafka的topic為了提高可用性及高吞吐,引入了topic的分區(qū),每個(gè)分區(qū)為了提高可用性,分區(qū)分為L(zhǎng)eaderpartition和Followerpartition,Leader partition對(duì)外提供讀寫(xiě)服務(wù),F(xiàn)ollowerpartition作為災(zāi)備提高可用性,整體的架構(gòu)如下圖;

圖片圖片

4.1.3 部署層

4.1.3.1 業(yè)界部署架構(gòu)的演進(jìn)

部署層是通過(guò)不斷突破單機(jī)器,單機(jī)房,單地域,做到機(jī)器級(jí)別,機(jī)房級(jí)別,地域級(jí)別的容災(zāi)來(lái)保證系統(tǒng)的高可用。核心思想是通過(guò)冗余以及負(fù)載均衡進(jìn)行容災(zāi)保證高可用。

圖片圖片

4.1.3.2 我們部署架構(gòu)現(xiàn)狀

目前我們的應(yīng)用都是采用多機(jī)房多分組Docker容器化部署,會(huì)根據(jù)業(yè)務(wù)方的重要程度及流量大小設(shè)置不同的別名,隔離到不同的分組中對(duì)外提供服務(wù)。

?應(yīng)用容器機(jī)房為:中云信,有孚,廊坊,宿遷等;

?數(shù)據(jù)庫(kù)Mysql雙機(jī)房部署:中云信,有孚;

?緩存Redis雙機(jī)房部署:中云信,有孚;

?ES單機(jī)房部署:有孚;

圖片 圖片

責(zé)任編輯:武曉燕 來(lái)源: 京東云開(kāi)發(fā)者
相關(guān)推薦

2021-10-18 11:58:56

負(fù)載均衡虛擬機(jī)

2022-09-06 08:02:40

死鎖順序鎖輪詢(xún)鎖

2021-01-19 05:49:44

DNS協(xié)議

2022-09-14 09:01:55

shell可視化

2022-09-08 10:14:29

人臉識(shí)別算法

2020-07-15 08:57:40

HTTPSTCP協(xié)議

2020-11-16 10:47:14

FreeRTOS應(yīng)用嵌入式

2024-11-28 08:00:00

2020-07-09 07:54:35

ThreadPoolE線(xiàn)程池

2024-03-07 18:11:39

Golang采集鏈接

2022-10-10 08:35:17

kafka工作機(jī)制消息發(fā)送

2022-07-19 16:03:14

KubernetesLinux

2020-12-23 08:37:28

PythonEXCEL熱點(diǎn)推薦

2023-06-12 08:49:12

RocketMQ消費(fèi)邏輯

2024-05-10 12:59:58

PyTorch人工智能

2021-08-26 05:02:50

分布式設(shè)計(jì)

2024-01-11 09:53:31

面試C++

2024-01-05 08:30:26

自動(dòng)駕駛算法

2022-07-15 16:31:49

Postman測(cè)試

2022-04-29 09:31:17

攜程酒店訂單系統(tǒng)數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)