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

為了做到微服務(wù)的高可用,鬼知道我出了多少?gòu)埮?/h1> 原創(chuàng)

開(kāi)發(fā) 架構(gòu) 開(kāi)發(fā)工具
高可用并不是一套整體解決方案,而是由諸多環(huán)節(jié)組成,一環(huán)扣一環(huán),鬼知道為了這些串聯(lián)起來(lái)的環(huán)節(jié),我得出多少?gòu)埮迫?yīng)對(duì),才能最終組成一個(gè)整個(gè)系統(tǒng)的高可用落地方案。

【51CTO.com原創(chuàng)稿件】高可用并不是一套整體解決方案,而是由諸多環(huán)節(jié)組成,一環(huán)扣一環(huán),鬼知道為了這些串聯(lián)起來(lái)的環(huán)節(jié),我得出多少?gòu)埮迫?yīng)對(duì),才能最終組成一個(gè)整個(gè)系統(tǒng)的高可用落地方案。

?[[271724]]??

圖片來(lái)自 Pexels

什么是高可用

在定義什么是高可用,可以先定義下什么是不可用,一個(gè)網(wǎng)站的內(nèi)容最終呈現(xiàn)在用戶面前需要經(jīng)過(guò)若干個(gè)環(huán)節(jié),而其中只要任何一個(gè)環(huán)節(jié)出現(xiàn)了故障,都可能導(dǎo)致網(wǎng)站頁(yè)面不可訪問(wèn),這個(gè)也就是網(wǎng)站不可用的情況。

參考維基百科,看看維基怎么定義高可用:

系統(tǒng)無(wú)中斷地執(zhí)行其功能的能力,代表系統(tǒng)的可用性程度,是進(jìn)行系統(tǒng)設(shè)計(jì)時(shí)的準(zhǔn)則之一。

這個(gè)難點(diǎn)或是重點(diǎn)在于“無(wú)中斷”,要做到 7x24 小時(shí)無(wú)中斷無(wú)異常的服務(wù)提供。

為什么需要高可用

一套對(duì)外提供服務(wù)的系統(tǒng)是需要硬件,軟件相結(jié)合,但是我們的硬件總是會(huì)出故障,軟件會(huì)有 Bug,硬件會(huì)慢慢老化,網(wǎng)絡(luò)總是不穩(wěn)定,軟件會(huì)越來(lái)越復(fù)雜和龐大。

除了硬件軟件在本質(zhì)上無(wú)法做到“無(wú)中斷”,外部環(huán)境也可能導(dǎo)致服務(wù)的中斷,例如斷電,地震,火災(zāi),光纖被挖掘機(jī)挖斷,這些影響的程度可能更大。

高可用的評(píng)價(jià)緯度

在業(yè)界有一套比較出名的評(píng)定網(wǎng)站可用性的指標(biāo),常用 N 個(gè) 9 來(lái)量化可用性,可以直接映射到網(wǎng)站正常運(yùn)行時(shí)間的百分比上:

???

之前就職的一家互聯(lián)網(wǎng)公司也是按照這個(gè)指標(biāo)去界定可用性,不過(guò)在執(zhí)行的過(guò)程中也碰到了一些問(wèn)題。

例如,有一些服務(wù)的升級(jí)或數(shù)據(jù)遷移明明可以在深夜停機(jī)或停服務(wù)進(jìn)行,然而考慮到以后的報(bào)告要顯示出我們的系統(tǒng)達(dá)到了多少個(gè) 9 的高可用,而放棄停服務(wù)這種簡(jiǎn)單的解決方案,例如停機(jī) 2 個(gè)小時(shí),就永遠(yuǎn)也達(dá)不到 4 個(gè) 9。

然而在一些高并發(fā)的場(chǎng)合,例如在秒殺或拼團(tuán),雖然服務(wù)停止了幾分鐘,但是這個(gè)對(duì)整個(gè)公司業(yè)務(wù)的影響可能是非常重大的,分分鐘丟失的訂單可能是一個(gè)龐大的數(shù)量。

所以 N 個(gè) 9 來(lái)量化可用性其實(shí)也得考慮業(yè)務(wù)的情況。

微服務(wù)高可用設(shè)計(jì)手段

高可用是一個(gè)比較復(fù)雜的命題,基本上在所有的處理中都會(huì)涉及到高可用,所有在設(shè)計(jì)高可用方案也涉及到了方方面面。

?[[271725]]??

這中間將會(huì)出現(xiàn)的細(xì)節(jié)是多種多樣的,所以我們需要對(duì)這樣一個(gè)微服務(wù)高可用方案進(jìn)行一個(gè)頂層的設(shè)計(jì),圍繞服務(wù)高可用,先檢查下我們手里有多少?gòu)埮啤?/p>

服務(wù)冗余

?[[271726]]??

①冗余策略

每一個(gè)訪問(wèn)可能都會(huì)有多個(gè)服務(wù)組合而成,每個(gè)機(jī)器每個(gè)服務(wù)都可能出現(xiàn)問(wèn)題,所以第一個(gè)考慮到的就是每個(gè)服務(wù)必須不止一份可以是多份。

所謂多份一致的服務(wù)就是服務(wù)的冗余,這里說(shuō)的服務(wù)泛指了機(jī)器的服務(wù),容器的服務(wù),還有微服務(wù)本身的服務(wù)。

在機(jī)器服務(wù)層面需要考慮,各個(gè)機(jī)器間的冗余是否有在物理空間進(jìn)行隔離冗余。

例如是否所有機(jī)器分別部署在不同機(jī)房,如果在同一個(gè)機(jī)房是否做到了部署在不同的機(jī)柜,如果是 Docker 容器是否部署在分別不同的物理機(jī)上面。

采取的策略其實(shí)也還是根據(jù)服務(wù)的業(yè)務(wù)而定,所以需要對(duì)服務(wù)進(jìn)行分級(jí)評(píng)分,從而采取不同的策略。

不同的策略安全程度不同,伴隨著的成本也是不同,安全等級(jí)更高的服務(wù)可能還不止考慮不同機(jī)房,還需要把各個(gè)機(jī)房所處的區(qū)域考慮進(jìn)行。

例如,兩個(gè)機(jī)房不要處在同一個(gè)地震帶上等等。

???

②無(wú)狀態(tài)化

服務(wù)的冗余會(huì)要求我們可以隨時(shí)對(duì)服務(wù)進(jìn)行擴(kuò)容或者縮容,有可能我們會(huì)從 2 臺(tái)機(jī)器變成 3 臺(tái)機(jī)器。

想要對(duì)服務(wù)進(jìn)行隨時(shí)隨地的擴(kuò)縮容,就要求我們的服務(wù)是一個(gè)無(wú)狀態(tài)化,所謂無(wú)狀態(tài)化就是每個(gè)服務(wù)的服務(wù)內(nèi)容和數(shù)據(jù)都是一致的。

例如,從我們的微服務(wù)架構(gòu)來(lái)看,我們總共分水平劃分了好幾個(gè)層,正因?yàn)槲覀兠總€(gè)層都做到了無(wú)狀態(tài),所以在這個(gè)水平架構(gòu)的擴(kuò)張是非常的簡(jiǎn)單。

假設(shè),我們需要對(duì)網(wǎng)關(guān)進(jìn)行擴(kuò)容,我們只需要增加服務(wù)就可以,而不需要去考慮網(wǎng)關(guān)是否存儲(chǔ)了一個(gè)額外的數(shù)據(jù)。

???

網(wǎng)關(guān)不保存任何的 Session 數(shù)據(jù),不提供會(huì)造成一致性的服務(wù),將不一致的數(shù)據(jù)進(jìn)行幾種存儲(chǔ),借助更加擅長(zhǎng)數(shù)據(jù)同步的中間件來(lái)完成。

這個(gè)是目前主流的方案,服務(wù)本身盡可能提供邏輯的服務(wù),將數(shù)據(jù)的一致性保證集中式處理,這樣就可以把“狀態(tài)”抽取出來(lái),讓網(wǎng)關(guān)保持一個(gè)“無(wú)狀態(tài)”。

這里僅僅是舉了網(wǎng)關(guān)的例子,在微服務(wù)基本所有的服務(wù),都應(yīng)該按照這種思路去做。

如果服務(wù)中有狀態(tài),就應(yīng)該把狀態(tài)抽取出來(lái),讓更加擅長(zhǎng)處理數(shù)據(jù)的組件來(lái)處理,而不是在微服務(wù)中去兼容有數(shù)據(jù)的狀態(tài)。

數(shù)據(jù)存儲(chǔ)高可用

?[[271729]]??

之前上面說(shuō)的服務(wù)冗余,可以簡(jiǎn)單的理解為計(jì)算的高可用,計(jì)算高可用只需要做到無(wú)狀態(tài)既可簡(jiǎn)單的擴(kuò)容縮容,但是對(duì)于需要存儲(chǔ)數(shù)據(jù)的系統(tǒng)來(lái)說(shuō),數(shù)據(jù)本身就是有狀態(tài)。

跟存儲(chǔ)與計(jì)算相比,有一個(gè)本質(zhì)的差別:將數(shù)據(jù)從一臺(tái)機(jī)器搬到另一臺(tái)機(jī)器,需要經(jīng)過(guò)線路進(jìn)行傳輸。

網(wǎng)絡(luò)是不穩(wěn)定的,特別是跨機(jī)房的網(wǎng)絡(luò),Ping 的延時(shí)可能是幾十幾百毫秒,雖然毫秒對(duì)于人來(lái)說(shuō)幾乎沒(méi)有什么感覺(jué),但是對(duì)于高可用系統(tǒng)來(lái)說(shuō),就是本質(zhì)上的不同,這意味著整個(gè)系統(tǒng)在某個(gè)時(shí)間點(diǎn)上,數(shù)據(jù)肯定是不一致的。

按照“數(shù)據(jù)+邏輯=業(yè)務(wù)”的公式來(lái)看,數(shù)據(jù)不一致,邏輯一致,最后的業(yè)務(wù)表現(xiàn)也會(huì)不一致。

舉個(gè)例子:

???

無(wú)論是正常情況下的傳輸延時(shí),還是異常情況下的傳輸中斷,都會(huì)導(dǎo)致系統(tǒng)的數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)出現(xiàn)不一致。

而數(shù)據(jù)的不一致又會(huì)導(dǎo)致業(yè)務(wù)出現(xiàn)問(wèn)題,但是如果數(shù)據(jù)不做冗余,系統(tǒng)的高可用無(wú)法保證。

所以,存儲(chǔ)高可用的難點(diǎn)不在于怎么備份數(shù)據(jù),而在于如何減少或者規(guī)避數(shù)據(jù)不一致對(duì)業(yè)務(wù)造成的影響。

分布式領(lǐng)域中有一個(gè)著名的 CAP 定理,從理論上論證了存儲(chǔ)高可用的復(fù)雜度,也就是說(shuō),存儲(chǔ)高可用不可能同時(shí)滿足“一致性,可用性,分區(qū)容錯(cuò)性”。

最多只能滿足 2 個(gè),其中分區(qū)容錯(cuò)在分布式中是必須的,就意味著,我們?cè)谧黾軜?gòu)設(shè)計(jì)時(shí)必須結(jié)合業(yè)務(wù)對(duì)一致性和可用性進(jìn)行取舍。

存儲(chǔ)高可用方案的本質(zhì)是將數(shù)據(jù)復(fù)制到多個(gè)存儲(chǔ)設(shè)備中,通過(guò)數(shù)據(jù)冗余的方式來(lái)實(shí)現(xiàn)高可用,其復(fù)雜度主要呈現(xiàn)在數(shù)據(jù)復(fù)制的延遲或中斷導(dǎo)致數(shù)據(jù)的不一致性。

我們?cè)谠O(shè)計(jì)存儲(chǔ)架構(gòu)時(shí)必須考慮到以下幾個(gè)方面:


  • 數(shù)據(jù)怎么進(jìn)行復(fù)制
  • 架構(gòu)中每個(gè)節(jié)點(diǎn)的職責(zé)是什么
  • 數(shù)據(jù)復(fù)制出現(xiàn)延遲怎么處理
  • 當(dāng)架構(gòu)中節(jié)點(diǎn)出現(xiàn)錯(cuò)誤怎么保證高可用

①數(shù)據(jù)主從復(fù)制

主從復(fù)制是最常見(jiàn)的也是最簡(jiǎn)單的存儲(chǔ)高可用方案,例如 MySQL,Redis 等等。

???

其架構(gòu)的優(yōu)點(diǎn)就是簡(jiǎn)單,主機(jī)復(fù)制寫(xiě)和讀,而從機(jī)只負(fù)責(zé)讀操作,在讀并發(fā)高時(shí)候可用擴(kuò)張從庫(kù)的數(shù)量減低壓力,主機(jī)出現(xiàn)故障,讀操作也可以保證讀業(yè)務(wù)的順利進(jìn)行。

缺點(diǎn)就是客戶端必須感知主從關(guān)系的存在,將不同的操作發(fā)送給不同的機(jī)器進(jìn)行處理。

而且主從復(fù)制中,從機(jī)器負(fù)責(zé)讀操作,可能因?yàn)橹鲝膹?fù)制時(shí)延大,出現(xiàn)數(shù)據(jù)不一致性的問(wèn)題。

②數(shù)據(jù)主從切換

剛說(shuō)了主從切換存在兩個(gè)問(wèn)題:

主機(jī)故障寫(xiě)操作無(wú)法進(jìn)行。

需要人工將其中一臺(tái)從機(jī)器升級(jí)為主機(jī)。

為了解決這個(gè)兩個(gè)問(wèn)題,我們可以設(shè)計(jì)一套主從自動(dòng)切換的方案,其中涉及到對(duì)主機(jī)的狀態(tài)檢測(cè),切換的決策,數(shù)據(jù)丟失和沖突的問(wèn)題。

主機(jī)狀態(tài)檢測(cè):需要多個(gè)檢查點(diǎn)來(lái)檢測(cè)主機(jī)的機(jī)器是否正常,進(jìn)程是否存在,是否出現(xiàn)超時(shí),是否寫(xiě)操作不可執(zhí)行,是否讀操作不可執(zhí)行,將其進(jìn)行匯總,交給切換決策。

切換決策:確定切換的時(shí)間決策,什么情況下從機(jī)就應(yīng)該升級(jí)為主機(jī),是進(jìn)程不存在,是寫(xiě)操作不可行,連續(xù)檢測(cè)多少失敗次就進(jìn)行切換。

應(yīng)該選擇哪一個(gè)從節(jié)點(diǎn)升級(jí)為主節(jié)點(diǎn),一般來(lái)說(shuō)或應(yīng)該選同步步驟最大的從節(jié)點(diǎn)來(lái)進(jìn)行升級(jí)。切換是自動(dòng)切換還是半自動(dòng)切換,通過(guò)報(bào)警方式,讓人工做一次確認(rèn)。

數(shù)據(jù)丟失和數(shù)據(jù)沖突:數(shù)據(jù)寫(xiě)到主機(jī),還沒(méi)有復(fù)制到從機(jī),主機(jī)就掛了,這個(gè)時(shí)候怎么處理,這個(gè)也得考慮業(yè)務(wù)的方式,是要確保 CP 或 AP。

???

還要考慮一個(gè)數(shù)據(jù)沖突的問(wèn)題,這個(gè)問(wèn)題在 MySQL 中大部分是由自增主鍵引起。

就算不考慮自增主鍵會(huì)引起數(shù)據(jù)沖突的問(wèn)題,其實(shí)自增主鍵還要引起很多的問(wèn)題,這里不細(xì)說(shuō),避免使用自增主鍵。

③數(shù)據(jù)分片

上述的數(shù)據(jù)冗余可以通過(guò)數(shù)據(jù)的復(fù)制來(lái)進(jìn)行解決,但是數(shù)據(jù)的擴(kuò)張需要通過(guò)數(shù)據(jù)的分片來(lái)進(jìn)行解決(如果在關(guān)系型數(shù)據(jù)庫(kù)是分表)。

???

何為數(shù)據(jù)分片(Segment,F(xiàn)ragment, Shard, Partition),就是按照一定的規(guī)則,將數(shù)據(jù)集劃分成相互獨(dú)立、正交的數(shù)據(jù)子集,然后將數(shù)據(jù)子集分布到不同的節(jié)點(diǎn)上。

HDFS , MongoDB 的 Sharding 模式也基本是基于這種分片的模式去實(shí)現(xiàn)。

我們?cè)谠O(shè)計(jì)分片主要考慮到的點(diǎn)是:


  • 做數(shù)據(jù)分片,如何將數(shù)據(jù)映射到節(jié)點(diǎn)。
  • 數(shù)據(jù)分片的特征值,即按照數(shù)據(jù)中的哪一個(gè)屬性(字段)來(lái)分片。
  • 數(shù)據(jù)分片的元數(shù)據(jù)的管理,如何保證元數(shù)據(jù)服務(wù)器的高性能、高可用,如果是一組服務(wù)器,如何保證強(qiáng)一致性。

柔性化/異步化

?[[271733]]??

①異步化

在每一次調(diào)用,時(shí)間越長(zhǎng)存在超時(shí)的風(fēng)險(xiǎn)就越大,邏輯越復(fù)雜執(zhí)行的步驟越多,存在失敗的風(fēng)險(xiǎn)也就越大。

如果在業(yè)務(wù)允許的情況下,用戶調(diào)用只給用戶必須要的結(jié)果,而不是需要同步的結(jié)果可以放在另外的地方異步去操作,這就減少了超時(shí)的風(fēng)險(xiǎn)也把復(fù)雜業(yè)務(wù)進(jìn)行拆分減低復(fù)雜度。

當(dāng)然異步化的好處是非常多,例如削峰解耦等等,這里只是從可用的角度出發(fā)。

異步化大致有這三種的實(shí)現(xiàn)方式:


  • 服務(wù)端接收到請(qǐng)求后,創(chuàng)建新的線程處理業(yè)務(wù)邏輯,服務(wù)端先回應(yīng)答給客戶端。

???


  • 服務(wù)端接收到請(qǐng)求后,服務(wù)端先回應(yīng)答給客戶端,再繼續(xù)處理業(yè)務(wù)邏輯。

???


  • 服務(wù)端接收到請(qǐng)求后,服務(wù)端把信息保存在消息隊(duì)列或者數(shù)據(jù)庫(kù),回應(yīng)答給客戶端,服務(wù)端業(yè)務(wù)處理進(jìn)程再?gòu)南㈥?duì)列或者數(shù)據(jù)庫(kù)上讀取信息處理業(yè)務(wù)邏輯。

???

②柔性化

什么是柔性化?想象一個(gè)場(chǎng)景,我們的系統(tǒng)會(huì)給每個(gè)下單的用戶增加他們下單金額對(duì)應(yīng)的積分,當(dāng)一個(gè)用戶下單完畢后,我們給他增加積分的服務(wù)出現(xiàn)了問(wèn)題。

這個(gè)時(shí)候,我們是要取消掉這個(gè)訂單還是先讓訂單通過(guò),積分的問(wèn)題通過(guò)重新或者報(bào)警來(lái)處理呢?

所謂的柔性化,就是在我們業(yè)務(wù)中允許的情況下,做不到給予用戶百分百可用的,通過(guò)降級(jí)的手段給到用戶盡可能多的服務(wù),而不是非得每次都交出去要么 100 分或 0 分的答卷。

怎么去做柔性化,更多其實(shí)是對(duì)業(yè)務(wù)的理解和判斷,柔性化更多是一種思維,需要對(duì)業(yè)務(wù)場(chǎng)景有深入的了解。

在電商訂單的場(chǎng)景中,下單,扣庫(kù)存,支付是一定要執(zhí)行的步驟,如果失敗則訂單失敗。

???

但是加積分,發(fā)貨,售后是可以柔性處理,就算出錯(cuò)也可以通過(guò)日志報(bào)警讓人工去檢查,沒(méi)必要為加積分損失整個(gè)下單的可用性。

兜底/容錯(cuò)

?[[271738]]??

兜底可能是我們經(jīng)常談?wù)摰囊环N降級(jí)的方案,方案是用來(lái)實(shí)施,但是這里兜底可能更多是一種思想,更多的是一種預(yù)案,每個(gè)操作都可以犯錯(cuò),我們也可以接受犯錯(cuò)。

但是每個(gè)犯錯(cuò)我們都必須有一個(gè)兜底的預(yù)案,這個(gè)兜底的預(yù)案其實(shí)就是我們的容錯(cuò)或者說(shuō)最大程度避免更大傷害的措施,實(shí)際上也是一個(gè)不斷降級(jí)的過(guò)程。

舉個(gè)例子:

???

例如我們首頁(yè)請(qǐng)求的用戶個(gè)性化推薦商品的接口,發(fā)現(xiàn)推薦系統(tǒng)出錯(cuò),我們不應(yīng)該去擴(kuò)大(直接把異常拋給用戶)或保持調(diào)用接口的錯(cuò)誤,而是應(yīng)該兼容調(diào)用接口的錯(cuò)誤,做到更加柔性化。

這時(shí)候可以選擇獲取之前沒(méi)有失敗接口的緩存數(shù)據(jù),如果沒(méi)有則可以獲取通用商品不用個(gè)性化推薦,如果也沒(méi)有可以讀取一些靜態(tài)文字進(jìn)行展示。

由于我們架構(gòu)進(jìn)行了分層,分層 App,網(wǎng)關(guān),業(yè)務(wù)邏輯層,數(shù)據(jù)訪問(wèn)層等等,在組織結(jié)構(gòu)也進(jìn)行了劃分,與之對(duì)應(yīng)的是前端組,后端業(yè)務(wù)邏輯組,甚至有中臺(tái)組等等。

既然有代碼和人員架構(gòu)的層級(jí)劃分,那么每一層都必須有這樣的思想:包容下一層的錯(cuò)誤,為上一層提供盡可能無(wú)錯(cuò)的服務(wù)。

舉個(gè)例子:

???

商品的美元售價(jià)假設(shè)要用商品人民幣售價(jià)/匯率,這個(gè)時(shí)候錯(cuò)誤發(fā)生在低層的數(shù)據(jù)層,上一層如果直接進(jìn)行除,肯定就拋出 java.lang.ArithmeticException: / by zero。

本著我們對(duì)任何一層調(diào)用服務(wù)都不可信的原則,應(yīng)該對(duì)其進(jìn)行容錯(cuò)處理,不能讓異常擴(kuò)散,更要保證我們這一層對(duì)上一次盡可能的作出最大努力確定的服務(wù)。

負(fù)載均衡

?[[271739]]??

相信負(fù)載均衡這個(gè)話題基本已經(jīng)深入每個(gè)做微服務(wù)開(kāi)發(fā)或設(shè)計(jì)者的人心,負(fù)載均衡的實(shí)現(xiàn)有硬件和軟件。

硬件有 F5,A10 等機(jī)器;軟件有 LVS,Nginx,HAProxy 等等,負(fù)載均衡的算法有 Random,RoundRobin,ConsistentHash 等等。

①Nginx 負(fù)載均衡故障轉(zhuǎn)移

???

轉(zhuǎn)移流程:Nginx 根據(jù)給定好的負(fù)載均衡算法進(jìn)行調(diào)度,當(dāng)請(qǐng)求到 Tomcat1,Nginx 發(fā)現(xiàn) Tomcat1 出現(xiàn)連接錯(cuò)誤(節(jié)點(diǎn)失效),Nginx 會(huì)根據(jù)一定的機(jī)制將 Tomcat1 從調(diào)用的負(fù)載列表中清除。

在下一次請(qǐng)求,Nginx 不會(huì)分配請(qǐng)求到有問(wèn)題的 Tomcat1 上面,會(huì)將請(qǐng)求轉(zhuǎn)移到其他的 Tomcat 之上。

節(jié)點(diǎn)失效:Nginx 默認(rèn)判斷節(jié)點(diǎn)失效是以 connect refuse 和 timeout 為標(biāo)準(zhǔn),在對(duì)某個(gè)節(jié)點(diǎn)進(jìn)行 fails 累加,當(dāng) fails 大于 max_fails 時(shí),該節(jié)點(diǎn)失效。

節(jié)點(diǎn)恢復(fù):當(dāng)某個(gè)節(jié)點(diǎn)失敗的次數(shù)大于 max_fails 時(shí),但不超過(guò) fail_timeout,Nginx 將不再對(duì)該節(jié)點(diǎn)進(jìn)行探測(cè),直到超過(guò)失效時(shí)間或者所有的節(jié)點(diǎn)都失效,Nginx 會(huì)對(duì)節(jié)點(diǎn)進(jìn)行重新探測(cè)。

②ZK 負(fù)載均衡故障轉(zhuǎn)移

???

在使用 ZK 作為注冊(cè)中心時(shí),故障的發(fā)現(xiàn)是由 ZK 去進(jìn)行發(fā)現(xiàn),業(yè)務(wù)邏輯層通過(guò) Watch 的心跳機(jī)制將自己注冊(cè)到 ZK 上,網(wǎng)關(guān)對(duì) ZK 進(jìn)行訂閱就可以知道有多少可以調(diào)用的列表。

當(dāng)業(yè)務(wù)邏輯層在重啟或者被關(guān)閉時(shí)就會(huì)跟 ZK 斷了心跳,ZK 會(huì)更新可調(diào)用列表。

使用 ZK 作為負(fù)載均衡的協(xié)調(diào)器,最大的問(wèn)題是 ZK 對(duì)于服務(wù)是否可用是基于 Pingpong 的方式。

只要服務(wù)心跳存在,ZK 就認(rèn)為服務(wù)是處在可用狀態(tài),但是服務(wù)如果處在假死的狀態(tài),ZK 是無(wú)從得知的。這個(gè)時(shí)候,業(yè)務(wù)邏輯服務(wù)是否真正可用只能夠由網(wǎng)關(guān)知道。

冪等設(shè)計(jì):為何會(huì)牽出冪等設(shè)計(jì)的問(wèn)題,主要是因?yàn)樨?fù)載均衡的 Failover 策略,就是對(duì)失敗的服務(wù)會(huì)進(jìn)行重試。

一般來(lái)說(shuō),如果是讀操作的服務(wù),重復(fù)執(zhí)行也不會(huì)出問(wèn)題,但想象一下,如果是一個(gè)創(chuàng)建訂單減庫(kù)存的操作,第一次調(diào)用也 Tomcat1 超時(shí),再重新調(diào)用了 Tomcat2。

這個(gè)時(shí)候我們都不能確認(rèn)超時(shí)調(diào)用的 Tomcat1 是否真的被調(diào)用,有可能根本就調(diào)用不成功,有可能已經(jīng)調(diào)用成功但是因?yàn)槟承┰蚍祷爻瑫r(shí)而已。

所以,很大程度這個(gè)接口會(huì)被調(diào)用 2 次。如果我們沒(méi)有保證冪等性,就有可能一個(gè)訂單導(dǎo)致了減少 2 次的庫(kù)存。

所謂的冪等性,就是得保證在同一個(gè)業(yè)務(wù)中,一個(gè)接口被調(diào)用了多次,其導(dǎo)致的結(jié)果都是一樣的。

服務(wù)限流降級(jí)熔斷

?[[271741]]??

先來(lái)講講微服務(wù)中限流/熔斷的目的是什么,微服務(wù)后,系統(tǒng)分布式部署,系統(tǒng)之間通過(guò) RPC 框架通信,整個(gè)系統(tǒng)發(fā)生故障的概率隨著系統(tǒng)規(guī)模的增長(zhǎng)而增長(zhǎng),一個(gè)小的故障經(jīng)過(guò)鏈路的傳遞放大,有可能會(huì)造成更大的故障。

限流跟高可用的關(guān)系是什么?假定我們的系統(tǒng)最多只能承受 500 個(gè)人的并發(fā)訪問(wèn),但某個(gè)時(shí)候突然增加到 1000 個(gè)人進(jìn)來(lái),一下子就把整個(gè)系統(tǒng)給壓垮了。

本來(lái)還有 500 個(gè)人能享受到我們系統(tǒng)的服務(wù),突然間變成了所有人都無(wú)法得到服務(wù)。

與其讓 1000 人都無(wú)法得到服務(wù),不如就讓 500 個(gè)人得到服務(wù),拒絕掉另外 500 個(gè)人。限流是對(duì)訪問(wèn)的隔離,是保證了部門(mén)系統(tǒng)承受范圍內(nèi)用戶的可用性。

熔斷跟高可用的關(guān)系是什么?上面說(shuō)了微服務(wù)是一個(gè)錯(cuò)綜復(fù)雜的調(diào)用鏈關(guān)系,假設(shè)模塊 A 調(diào)用模塊 B,模塊 B 又調(diào)用了模塊 C,模塊 C 調(diào)用了模塊 D。

這個(gè)時(shí)候,模塊 D 出了問(wèn)題出現(xiàn)嚴(yán)重的時(shí)延,這個(gè)時(shí)候,整個(gè)調(diào)用鏈就會(huì)被模塊 D 給拖垮。

A 等 B,B 等 C,C 等 D,而且 A B C D 的資源被鎖死得不到釋放,如果流量大的話還容易引起雪崩。

熔斷,主動(dòng)丟棄模塊 D 的調(diào)用,并在功能上作出一些降級(jí)才能保證到我們系統(tǒng)的健壯性。熔斷是對(duì)模塊的隔離,是保證了最大功能的可用性。

服務(wù)治理

?[[271742]]??

①服務(wù)模塊劃分

服務(wù)模塊與服務(wù)模塊之間有著千絲萬(wàn)縷的關(guān)系,但服務(wù)模塊在業(yè)務(wù)中各有權(quán)重。

例如訂單模塊可能是一家電商公司的重中之重,如果出問(wèn)題將會(huì)直接影響整個(gè)公司的營(yíng)收。

而一個(gè)后臺(tái)的查詢服務(wù)模塊可能也重要,但它的重要等級(jí)絕對(duì)是沒(méi)有像訂單這么重要。

所以,在做服務(wù)治理時(shí),必須明確各個(gè)服務(wù)模塊的重要等級(jí),這樣才能更好的做好監(jiān)控,分配好資源。

這個(gè)在各個(gè)公司有各個(gè)公司的一個(gè)標(biāo)準(zhǔn),例如在電商公司,確定服務(wù)的級(jí)別可能會(huì)更加傾向?qū)τ脩粽?qǐng)求數(shù)和營(yíng)收相關(guān)的作為指標(biāo)。

???

可能真正的劃分要比這個(gè)更為復(fù)雜,必須根據(jù)具體業(yè)務(wù)去定,這個(gè)可以從平時(shí)服務(wù)模塊的訪問(wèn)量和流量去預(yù)估。

往往更重要的模塊也會(huì)提供更多的資源,所以不僅要對(duì)技術(shù)架構(gòu)了如指掌,還要對(duì)公司各種業(yè)務(wù)形態(tài)了然于心才可以。

服務(wù)分級(jí)不僅僅在故障界定起到重要主要,而且決定了服務(wù)監(jiān)控的力度,服務(wù)監(jiān)控在高可用中起到了一個(gè)保障的作用。

它不僅可以保留服務(wù)崩潰的現(xiàn)場(chǎng)以等待日后復(fù)盤(pán),更重要的是它可以起到一個(gè)先知,先行判斷的角色,很多時(shí)候可以預(yù)先判斷危險(xiǎn),防范于未然。

②服務(wù)監(jiān)控

服務(wù)監(jiān)控是微服務(wù)治理的一個(gè)重要環(huán)節(jié),監(jiān)控系統(tǒng)的完善程度直接影響到我們微服務(wù)質(zhì)量的好壞。

我們的微服務(wù)在線上運(yùn)行的時(shí)候有沒(méi)有一套完善的監(jiān)控體系能去了解到它的健康情況,對(duì)整個(gè)系統(tǒng)的可靠性和穩(wěn)定性是非常重要,可靠性和穩(wěn)定性是高可用的一個(gè)前提保證。

服務(wù)的監(jiān)控更多是對(duì)于風(fēng)險(xiǎn)的預(yù)判,在出現(xiàn)不可用之間就提前的發(fā)現(xiàn)問(wèn)題,如果系統(tǒng)獲取監(jiān)控報(bào)警系統(tǒng)能自我修復(fù)則可以將錯(cuò)誤消滅在無(wú)形,如果系統(tǒng)發(fā)現(xiàn)報(bào)警無(wú)法自我修復(fù)則可以通知人員提早進(jìn)行接入。

一個(gè)比較完善的微服務(wù)監(jiān)控體系需要涉及到哪些層次?如下圖,大致可以劃分為五個(gè)層次的監(jiān)控:

???

基礎(chǔ)設(shè)施監(jiān)控:例如網(wǎng)絡(luò),交換機(jī),路由器等低層設(shè)備,這些設(shè)備的可靠性穩(wěn)定性就直接影響到上層服務(wù)應(yīng)用的穩(wěn)定性。

所以需要對(duì)網(wǎng)絡(luò)的流量,丟包情況,錯(cuò)包情況,連接數(shù)等等這些基礎(chǔ)設(shè)施的核心指標(biāo)進(jìn)行監(jiān)控。

系統(tǒng)層監(jiān)控:涵蓋了物理機(jī),虛擬機(jī),操作系統(tǒng)這些都是屬于系統(tǒng)級(jí)別監(jiān)控的方面,對(duì)幾個(gè)核心指標(biāo)監(jiān)控,如 CPU 使用率,內(nèi)存占用率,磁盤(pán) IO 和網(wǎng)絡(luò)帶寬情況。

應(yīng)用層監(jiān)控:例如對(duì) URL 訪問(wèn)的性能,訪問(wèn)的調(diào)用數(shù),訪問(wèn)的延遲,還有對(duì)服務(wù)提供性能進(jìn)行監(jiān)控,服務(wù)的錯(cuò)誤率。

對(duì) SQL 也需要進(jìn)行監(jiān)控,查看是否有慢 SQL,對(duì)于 Cache 來(lái)說(shuō),需要監(jiān)控緩存的命中率和性能,每個(gè)服務(wù)的響應(yīng)時(shí)間和 QPS 等等。

業(yè)務(wù)監(jiān)控:比方說(shuō)一個(gè)電商網(wǎng)站,需要關(guān)注它的用戶登錄情況,注冊(cè)情況,下單情況,支付情況。

這些直接影響到實(shí)際觸發(fā)的業(yè)務(wù)交易情況,這個(gè)監(jiān)控可以提供給運(yùn)營(yíng)和公司高管他們需要關(guān)注的數(shù)據(jù),直接可能對(duì)公司戰(zhàn)略產(chǎn)生影響。

端用戶監(jiān)控:用戶通過(guò)瀏覽器,客戶端打開(kāi)連到到我們的服務(wù),那么在用戶端用戶的體驗(yàn)是怎么樣,用戶端的性能是怎么樣,有沒(méi)有產(chǎn)生錯(cuò)誤,這些信息也是需要進(jìn)行監(jiān)控并記錄下來(lái)。

如果沒(méi)有監(jiān)控,有可能用戶因?yàn)槟承┰虺鲥e(cuò)或者性能問(wèn)題造成體驗(yàn)非常的差,而我們并沒(méi)有感知。

這里面包括了,監(jiān)控用戶端的使用性能,返回碼,在哪些城市地區(qū)他們的使用情況是怎么樣,還有運(yùn)營(yíng)商的情況,包括電信,聯(lián)通用戶的連接情況。

我們需要進(jìn)一步去知道是否有哪些渠道哪些用戶接入的時(shí)候存在著問(wèn)題,包括我們還需要知道客戶端使用的操作系統(tǒng)瀏覽器的版本。

總結(jié)

?[[271743]]??

出了那么多張牌,出牌只是術(shù),真正的道還是得靜下心來(lái)看看整個(gè)服務(wù)高可用的本質(zhì)是什么。

隨著微服務(wù)架構(gòu)的相互調(diào)用越來(lái)越復(fù)雜,環(huán)節(jié)只會(huì)越來(lái)越多,只有建立清晰的架構(gòu)和層次才能理清楚每個(gè)環(huán)節(jié)高可用的保障,保持簡(jiǎn)單。

從手段看高可用

主要使用的技術(shù)手段是服務(wù)和數(shù)據(jù)的冗余備份和失效轉(zhuǎn)移,一組服務(wù)或一組數(shù)據(jù)都能在多節(jié)點(diǎn)上,之間相互備份。

當(dāng)一臺(tái)機(jī)器宕機(jī)或出現(xiàn)問(wèn)題的時(shí)候,可以從當(dāng)前的服務(wù)切換到其他可用的服務(wù),不影響系統(tǒng)的可用性,也不會(huì)導(dǎo)致數(shù)據(jù)丟失。

從架構(gòu)看高可用

保持簡(jiǎn)單的架構(gòu),目前多數(shù)網(wǎng)站采用的是比較經(jīng)典的分層架構(gòu),應(yīng)用層,服務(wù)層,數(shù)據(jù)層。

應(yīng)用層是處理一些業(yè)務(wù)邏輯,服務(wù)層提供一些數(shù)據(jù)和業(yè)務(wù)緊密相關(guān)服務(wù),數(shù)據(jù)層負(fù)責(zé)對(duì)數(shù)據(jù)進(jìn)行讀寫(xiě)。

簡(jiǎn)單的架構(gòu)可以使應(yīng)用層,服務(wù)層可以保持無(wú)狀態(tài)化進(jìn)行水平擴(kuò)展,這個(gè)屬于計(jì)算高可用。

相比計(jì)算高可用,在數(shù)據(jù)層思考的高可用則屬于數(shù)據(jù)高可用,數(shù)據(jù)高可用相比計(jì)算高可用需要考慮到數(shù)據(jù)的一致性問(wèn)題會(huì)更加的復(fù)雜。

這個(gè)時(shí)候 CAP 理論在里面會(huì)發(fā)揮關(guān)鍵的作用,究竟是選擇 AP 或 CP,這個(gè)得根據(jù)業(yè)務(wù)去選擇模型。

從硬件看高可用

首先得確認(rèn)硬件總是可能壞的,網(wǎng)絡(luò)總是不穩(wěn)定的。解決它的方法也是一個(gè)服務(wù)器不夠就來(lái)多幾個(gè),一個(gè)機(jī)柜不夠就來(lái)幾個(gè),一個(gè)機(jī)房不夠就來(lái)幾個(gè)。

從軟件看高可用

軟件的開(kāi)發(fā)不嚴(yán)謹(jǐn),發(fā)布不規(guī)范也是導(dǎo)致各種不可用出現(xiàn),通過(guò)控制軟件開(kāi)發(fā)過(guò)程質(zhì)量監(jiān)控,通過(guò)測(cè)試,預(yù)發(fā)布,灰度發(fā)布等手段也是減少不可用的措施。

從治理看高可用

一個(gè)系統(tǒng)在線上跑的好好的,但我們也不能確保它在下一秒會(huì)不會(huì)出現(xiàn)不可用狀態(tài)。

將服務(wù)規(guī)范化,事前做好服務(wù)分割,做好服務(wù)監(jiān)控,預(yù)判不可用的出現(xiàn),在不可用出現(xiàn)之前發(fā)現(xiàn)問(wèn)題,解決問(wèn)題。

【注:文章部分內(nèi)容參考 李云華《從 0 開(kāi)始學(xué)架構(gòu)》楊波老師《微服務(wù)》】

作者:陳于喆

簡(jiǎn)介:十余年的開(kāi)發(fā)和架構(gòu)經(jīng)驗(yàn),國(guó)內(nèi)較早一批微服務(wù)開(kāi)發(fā)實(shí)施者。曾任職國(guó)內(nèi)互聯(lián)網(wǎng)公司網(wǎng)易和唯品會(huì)高級(jí)研發(fā)工程師,后在創(chuàng)業(yè)公司擔(dān)任技術(shù)總監(jiān)/架構(gòu)師,目前在洋蔥集團(tuán)任職技術(shù)研發(fā)副總監(jiān)。

???

【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】


責(zé)任編輯:武曉燕 來(lái)源: 51CTO
相關(guān)推薦

2019-06-19 09:33:17

微服務(wù)面試電商

2019-08-08 10:18:15

運(yùn)維架構(gòu)技術(shù)

2017-09-13 13:42:09

微服務(wù)緩存架構(gòu)

2021-12-03 10:30:25

WOT技術(shù)峰會(huì)技術(shù)

2020-12-09 09:21:41

微服務(wù)架構(gòu)數(shù)據(jù)

2020-07-29 08:30:48

微服務(wù)架構(gòu)數(shù)據(jù)

2019-09-25 09:50:29

高可用微服務(wù)系統(tǒng)

2018-05-03 06:56:43

項(xiàng)目經(jīng)理代碼項(xiàng)目管理

2022-01-10 19:45:40

微服務(wù)GO系統(tǒng)

2019-10-31 09:03:12

Java集群微服務(wù)

2023-12-20 09:26:20

高可用高吞吐高擴(kuò)展性

2024-03-08 09:46:53

2017-09-25 12:11:14

高可用微服務(wù)架構(gòu)

2017-12-28 09:41:29

微服務(wù)網(wǎng)關(guān)容錯(cuò)

2023-02-06 09:32:17

服務(wù)接口高可用

2018-10-28 18:09:22

微服務(wù)Microservic架構(gòu)

2023-10-13 18:57:22

2020-05-06 09:10:46

AQS同步器CAS

2023-03-01 22:28:15

Redis高可用

2022-07-19 06:24:02

微服務(wù)高可用
點(diǎn)贊
收藏

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