溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么提高微服務(wù)架構(gòu)的可用性

發(fā)布時間:2021-12-21 16:56:45 來源:億速云 閱讀:124 作者:柒染 欄目:云計算

怎么提高微服務(wù)架構(gòu)的可用性,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

業(yè)界通常用多少個9來衡量系統(tǒng)的可用性,如99.99%表示一年中有1小時左右的不可用時間。任何一個服務(wù)的可用性都不會是100%,意味著在服務(wù)運行時間里還是有可能發(fā)生故障。當(dāng)把功能集中且運行在同一個應(yīng)用中的單體架構(gòu)拆分成多個相互獨立的微服務(wù)架構(gòu)后,雖然可以降低一損俱損的全局性故障風(fēng)險,但由于微服務(wù)之間存在大量的依賴關(guān)系, 隨著微服務(wù)個數(shù)的增多,依賴關(guān)系也將會變得越來越復(fù)雜,而且每個微服務(wù)都有可能發(fā)生故障,如果不能做好相互依賴的隔離,避免故障的連鎖反應(yīng),結(jié)果可能比單體更糟糕。

假設(shè)有100個微服務(wù),并且每個微服務(wù)只會發(fā)生1種故障,那么總共會有 2100 種不同的故障場景,而每個微服務(wù)自身可能不止1種故障。當(dāng)某個微服務(wù)發(fā)生故障時,如何確保不會導(dǎo)致其他依賴的微服務(wù)不可用, 如何確保系統(tǒng)自動降級把發(fā)生故障的微服務(wù)排除出去,如何確保故障不會擴展到整個系統(tǒng)? 那么如何有效確保微服務(wù)架構(gòu)的可用性將會成為挑戰(zhàn)。
設(shè)定一個用戶請求依賴5個微服務(wù)的協(xié)作完成(pod為K8S容器框架中的定義,為一組相同功能的容器)。

在一開始每個依賴的Service都是正常的,現(xiàn)假設(shè)有一個Service異常了,這時可能會有三種情況:

這個請求成功,假設(shè)因網(wǎng)絡(luò)異?;蝈礄C導(dǎo)致Service C某個節(jié)點不可用,但有高可用節(jié)點取代了這個失敗節(jié)點,這時Service C不受影響,依然可用。

這個請求是成功的,假設(shè)是Service D故障,而這個Service不是關(guān)鍵性的,運行失敗也可以繼續(xù)進(jìn)行,比如注冊用戶需要調(diào)用一個服務(wù)發(fā)送注冊成功的郵件給用戶,如果發(fā)郵件的這個Service不可用,但不會影響用戶的注冊,所以用戶注冊還是會成功,郵件可以等服務(wù)恢復(fù)后再發(fā)送,只有時間上的延遲。這時Service A不受影響,依然可用,如下圖所示:

這個請求失敗,比如異常的節(jié)點是Service E,而Service E是代碼級邏輯異常,所有高可用節(jié)點都不可用,這時需要將Service E進(jìn)行依賴隔離,否則ServiceA可能會受到ServiceE的影響而不可用。需要做一些措施確保Service A不會受影響,依然可用。



可以從以下幾個策略可以提高微服務(wù)架構(gòu)的可用性:

1) 失效轉(zhuǎn)移
提高服務(wù)的高可用性,最基本的原則就是消除單點,通過負(fù)載均衡技術(shù)構(gòu)建集群,所有的集群節(jié)點都是無狀態(tài)且完全對等的。如上面講的第1種情況。當(dāng)一個節(jié)點異常時,負(fù)載均衡服務(wù)器會把用戶發(fā)送的訪問請求發(fā)送到可用的節(jié)點上。對用戶來說,某個節(jié)點異常是無感的,用戶請求會透明的轉(zhuǎn)移到了可用的節(jié)點上執(zhí)行。 

2) 異步調(diào)用
避免一個服務(wù)失敗導(dǎo)致整個應(yīng)用請求失敗很重要的是使用異步調(diào)用。如上面講的第2種情況。如果采用的是同步調(diào)用,當(dāng)郵件服務(wù)異常時,會導(dǎo)致其他兩個服務(wù)也無法執(zhí)行,最終導(dǎo)致用戶注冊失敗。如果采用異步調(diào)用,Service A把用戶注冊信息發(fā)送給消息隊列后立即返回用戶注冊成功的響應(yīng),雖然郵件服務(wù)不能用,但是寫數(shù)據(jù)庫的服務(wù),權(quán)限開通等服務(wù)都能正常執(zhí)行。所以即使郵件不能發(fā)送成功,也不會影響其他服務(wù)的執(zhí)行,用戶注冊可順利完成。

3) 依賴隔離
用戶請求發(fā)送給Service A,Service A分配線程資源通過網(wǎng)絡(luò)遠(yuǎn)程調(diào)用其他的Service,假設(shè)調(diào)用Service E發(fā)生異常時,Service A中對Service E調(diào)用的線程就可能會響應(yīng)慢或僵死,而線程是系統(tǒng)的資源,如果短時間內(nèi)得不到釋放,在高并發(fā)的情況下資源就會被耗盡,結(jié)果會導(dǎo)致Service A也不可用,雖然其他的服務(wù)依然可用。



Service A的資源是有限的,比如Service A啟動時分配了400個線程,當(dāng)400個線程都因調(diào)用Service E時異常不能及時正常的釋放,如線程死鎖,響應(yīng)時間慢,導(dǎo)致 400個線程全部僵死在調(diào)用Service E上,這里Service A就沒有空閑的線程來接收新的用戶請求,這時就會導(dǎo)致Service A掛起或僵死。所以避免Service A被依賴的服務(wù)拖垮就是要確保Service A的線程資源不會被調(diào)用的依賴服務(wù)耗盡,在《Release It!》一書中總結(jié)了非常重要的兩條方法: 設(shè)置超時和使用斷路器。

  1. 設(shè)置超時
    在應(yīng)用中設(shè)置服務(wù)調(diào)用的超時時間后,一旦線程的執(zhí)行時間超過了所設(shè)置的時間,就拋出異常信息,自動斷開連接,這樣服務(wù)的線程就不會都長時間僵死在調(diào)用異常的服務(wù)上,導(dǎo)致沒有空閑線程接收新的用戶請求,可以避免Service A因為調(diào)用Server E 異常而被拖垮,自身不可用。所以通過網(wǎng)絡(luò)調(diào)用外部依賴服務(wù)時,都必須設(shè)置超時。

  2. 使用斷路器
    斷路器大家都不陌生,家里電表在電流過載或者短路時就會跳閘,如果不跳閘,電路就不斷開,電線就會升溫,造成火災(zāi)。有了斷路器之后,電流過載時就會自動跳閘斷開電路,避免引起更大的災(zāi)難。在程序中也是如此,當(dāng)知道服務(wù)調(diào)用某個依賴服務(wù)有大量超時的時候,再讓新的請求去訪問也只會超時,并不能得到想到的結(jié)果,還會消耗現(xiàn)有資源,增加負(fù)載,導(dǎo)致服務(wù)不可用。


這個時候使用斷路器就能避免這種資源浪費,在自身服務(wù)和依賴服務(wù)之間放一個斷路器,通過斷路器的監(jiān)控實時統(tǒng)計訪問的狀態(tài),當(dāng)訪問超時或者失敗達(dá)到某個閾值的時候(如50%請求超時,或者連續(xù)20次請失?。痛蜷_斷路器,那么后續(xù)的請求就直接返回失敗,而不是一個長時間的等待,再根據(jù)一個時間間隔(如30秒)或請求超時的情況(如0%的超時)嘗試關(guān)閉斷路器(或者更換保險絲),看依賴是否恢復(fù)服務(wù)了。

一個服務(wù)依賴多個服務(wù)時,如果其中一個非核心的依賴不可用,通過設(shè)置超時和使用斷路器,可以確保Service A在調(diào)用異常的Service E并不會導(dǎo)致自身的異常,在大部分情況下服務(wù)還能健康運轉(zhuǎn),可以很好的做到依賴隔離。

4)設(shè)置限流
在服務(wù)訪問的高峰期可能因為大量的并發(fā)導(dǎo)致性能下降,嚴(yán)重時將會有大量的請求排隊,可能會導(dǎo)致服務(wù)宕機。為了保證應(yīng)用的可用性,可拒絕低優(yōu)先級的調(diào)用,讓高優(yōu)先級的請求成功,避免所有調(diào)用都失敗的情況,并且為每個依賴服務(wù)提供一個小的線程池,如果線程池已滿調(diào)用將被立即拒絕,默認(rèn)不采用排隊,可以加速失敗判定時間。這樣的結(jié)果是有些用戶可以訪問,而有些用戶失敗,但失敗的用戶重新訪問又可以是正常的訪問。這樣能確保服務(wù)的可用性,而不是完全不可用。

雖然有了上面的一些可提高系統(tǒng)可用性的措施,但系統(tǒng)是復(fù)雜的,一個簡單的修復(fù)都有可能造成不可想像的后果,且系統(tǒng)又是動態(tài)的,有些系統(tǒng)可能一天都發(fā)布幾次,幾十次。在這種情況下 故障依然是不可避免的。比起半夜深睡或正在享受節(jié)假日的美好時光時系統(tǒng)故障來當(dāng)救火隊員,會做更多的措施來提高系統(tǒng)的可用性。比如在某些企業(yè)里會定期舉行生產(chǎn)環(huán)境的故障應(yīng)急演練。

過去都是在業(yè)務(wù)低峰時進(jìn)行人為故障測試高可用方案是否生效,包括主機,網(wǎng)絡(luò),應(yīng)用,存儲等每一層架構(gòu)都進(jìn)行演練,而現(xiàn)在也逐漸的在正常的生產(chǎn)時間進(jìn)行故障應(yīng)急演練,檢查系統(tǒng)的高可用性。問題在于可能在演練時能夠立即恢復(fù),但真實故障發(fā)生時還是會出現(xiàn)長時間故障得不到恢復(fù)的情況。一個是演練是按照已知的場景制定的方案實施,二是演練的范圍基本是高可用節(jié)點的切換或災(zāi)備系統(tǒng)的切換,第三個問題是這個演練是人為操作,需要全員的參與,并不會頻繁的舉行。但系統(tǒng)是動態(tài)的,這次是高可用的,不代表下周,或下個月還是高可用的。

當(dāng)單體架構(gòu)變成微服務(wù)架構(gòu)后,應(yīng)用層的演練就會變得復(fù)雜,就像前面提到的,如果每個服務(wù)只有一個故障可能都會有 2100種不同。因此需要有一種自動的故障測試方式來回避微服務(wù)化后演練實施的可操作性。

Netflix公司提出了一種自動故障測試的方案來提高微服務(wù)架構(gòu)的可用性。這個測試方案也是在生產(chǎn)環(huán)境中進(jìn)行,而故障測試的最終目的,是為了當(dāng)真的有故障發(fā)生時,生產(chǎn)環(huán)境不會停止服務(wù),并且整套系統(tǒng)可以在沒有人為干預(yù)的情況下,非常優(yōu)雅地通過降級將發(fā)生故障的部分組件排除出去。他們認(rèn)為如果只在測試環(huán)境中測試,而真實生產(chǎn)環(huán)境的業(yè)務(wù)壓力,業(yè)務(wù)場景,環(huán)境配置、網(wǎng)絡(luò)性能和硬件性能都沒有測試過,當(dāng)故障在生產(chǎn)環(huán)境中真實發(fā)生時發(fā)現(xiàn)緩解問題的方案可能會失效。而且這個測試只在工作時間運行,這樣工程師可以得到告警并及時響應(yīng)。

Netflix通過Peter Alvaro在論文《路徑驅(qū)動的故障注入(Lineage-driven fault injection)》中提到了一套名為“Molly”的算法和自身的故障注入測試FIT(failure injection testing)實現(xiàn)了這套安全地自動化故障注入測試。Molly是從一套系統(tǒng)的無故障狀態(tài)出發(fā),然后試圖去回答說“系統(tǒng)是如何達(dá)到目前這種無故障的狀態(tài)的?”簡單舉例介紹一下這個算法的原理。先利用自身的追蹤系統(tǒng)繪制一個樹來表示每個請求經(jīng)過的所有的微服務(wù)。



(A or R or P or B) 

在最開始,上圖中的四個節(jié)點都是必須的,且正常的。然后從這個正確輸出反推,隨機選擇一個節(jié)點注入故障,找到并構(gòu)建支持其正確性的邏輯鏈條圖 。當(dāng)節(jié)點注入故障后,這時可能有三種情況:

這個請求失敗,我們已經(jīng)找到一個節(jié)點會故障,從而我們可以刪除未來的實驗中包含這個故障。
這個請示是成功的-但這個失敗的節(jié)點不是關(guān)鍵性的
這個請求成功,有高可用節(jié)點取代了這個失敗

在這個例子中,首先在Ratings中注入失敗,但請求是成功的。說明Rating失敗并不會影響服務(wù)的使用,那就先把這個節(jié)點排除,重新繪制請求樹。
 


(A or P or B) and (A or P or B or R)

這時可以看到,請求可以通過(A or P or B)的方式實現(xiàn),也可以通過 (A or P or B or R)的方式實現(xiàn)。接下來再在Playlist中注入故障,這時請求還是成功的,因為請求轉(zhuǎn)發(fā)到備用節(jié)點上執(zhí)行,這里將會有一個新的節(jié)點可以訪問。
 



(A or PF or B) and (A or P or B) and (A or P or B or R)

這時可以更新公式,說明可以通過(A or PF or B) and (A or P or B) and (A or P or B or R)三種方式請求服務(wù)。然后通過這樣不停的測試直到遍歷完所有正確輸出,沒有失敗的節(jié)點可以找到。

Molly沒有規(guī)定怎么搜索空間,所以實現(xiàn)時會估算所有的方案,然后隨機選擇最小的方案的集合。比如,最后的方案可能是[{A}, {PF}, {B}, {P,PF}, {R,A}, {R,B} …]。先選擇所有的單節(jié)點注入失敗,再選擇所的有雙節(jié)點的組合注入失敗,依此類推。

這個測試的目的是在影響大量成員前找到和修復(fù)故障,在生產(chǎn)環(huán)境上進(jìn)行故障測試時,不能接受引起大量的問題節(jié)點。為了避免這個風(fēng)險,只能在指定的范圍構(gòu)建測試,指定的范圍包含兩個關(guān)鍵的概念:故障范圍(failure scope)和注入點(injection points)。故障范圍指的是,把一次故障測試可能產(chǎn)生的影響,限制在一個可控的范圍內(nèi),這個范圍可以小到某個特定的用戶或者設(shè)備,也可以大到所有用戶的1%。而注入點指的是系統(tǒng)內(nèi)計劃會發(fā)生故障的組件,比如RPC層,緩存層,或者持久層。
  


故障模擬測試從FIT服務(wù)把故障模擬元數(shù)據(jù)注入到Zuul(緣邊網(wǎng)關(guān)服務(wù))開始,如果請求符合故障范圍(failure scope)則注入失敗。這個故障可能是延遲服務(wù)調(diào)用,或達(dá)到持久層失敗。每個被接觸到的注入點(injection points)檢查這個請求的上下文是否為指定要被注入故障的組件,如果是,在這個注入點模擬故障。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI