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

架構(gòu)設(shè)計中如何應(yīng)對接口級故障?

開發(fā) 架構(gòu)
接口級故障的典型表現(xiàn)就是,系統(tǒng)并沒有宕機、網(wǎng)絡(luò)也沒有中斷,但業(yè)務(wù)卻出現(xiàn)問題了,例如業(yè)務(wù)響應(yīng)緩慢、大量訪問超時和大量訪問出現(xiàn)異常(給用戶彈出提示“無法連接數(shù)據(jù)庫”)。

在實際業(yè)務(wù)運行過程中,有一種故障影響可能沒有那么大,但發(fā)生的概率較高,這就是今天聊的接口級的故障。

接口級故障的典型表現(xiàn)就是,系統(tǒng)并沒有宕機、網(wǎng)絡(luò)也沒有中斷,但業(yè)務(wù)卻出現(xiàn)問題了,例如業(yè)務(wù)響應(yīng)緩慢、大量訪問超時和大量訪問出現(xiàn)異常(給用戶彈出提示“無法連接數(shù)據(jù)庫”)。

這類問題的主要原因在于系統(tǒng)壓力太大、負(fù)載太高,導(dǎo)致無法快速處理業(yè)務(wù)請求,由此引發(fā)更多的后續(xù)問題。最常見的情況就是,數(shù)據(jù)庫慢查詢將數(shù)據(jù)庫的服務(wù)器資源耗盡,導(dǎo)致讀寫超時,業(yè)務(wù)讀寫數(shù)據(jù)庫時要么無法連接數(shù)據(jù)庫、要么超時,最終用戶看到的現(xiàn)象就是訪問很慢,一會兒訪問拋出異常,一會兒訪問又是正常結(jié)果。

如果進一步探究,導(dǎo)致接口級故障的原因可以分為兩大類:

  • 內(nèi)部原因:包括程序bug導(dǎo)致死循環(huán),某個接口導(dǎo)致數(shù)據(jù)庫慢查詢,程序邏輯不完善導(dǎo)致耗盡內(nèi)存等。
  • 外部原因:包括黑客攻擊,促銷或者搶購引入了超出平時幾倍甚至幾十倍的用戶,第三方系統(tǒng)大量請求,第三方系統(tǒng)響應(yīng)緩慢等。

解決接口級故障的核心思想和異地多活基本類似,都是優(yōu)先保證核心業(yè)務(wù)優(yōu)先保證絕大部分用戶。常見的應(yīng)對方法有四種,降級、熔斷、限流和排隊,下面我會一一講解。

1. 降級

降級指系統(tǒng)將某些業(yè)務(wù)或者接口的功能降低,可以是只提供部分功能,也可以是完全停掉所有功能。

例如,論壇可以降級為只能看帖子,不能發(fā)帖子;也可以降級為只能看帖子和評論,不能發(fā)評論;而App的日志上傳接口,可以完全停掉一段時間,這段時間內(nèi)App都不能上傳日志。

降級的核心思想就是丟車保帥,優(yōu)先保證核心業(yè)務(wù)。

例如,對于論壇來說,90%的流量是看帖子,那我們就優(yōu)先保證看帖的功能;對于一個App來說,日志上傳接口只是一個輔助的功能,故障時完全可以停掉。

常見的實現(xiàn)降級的方式有兩種:

1.1 系統(tǒng)后門降級

簡單來說,就是系統(tǒng)預(yù)留了后門用于降級操作。例如,系統(tǒng)提供一個降級URL,當(dāng)訪問這個URL時,就相當(dāng)于執(zhí)行降級指令,具體的降級指令通過URL的參數(shù)傳入即可。這種方案有一定的安全隱患,所以也會在URL中加入密碼這類安全措施。

系統(tǒng)后門降級的方式實現(xiàn)成本低,但主要缺點是如果服務(wù)器數(shù)量多,需要一臺一臺去操作,效率比較低,這在故障處理爭分奪秒的場景下是比較浪費時間的。

1.2 獨立降級系統(tǒng)

為了解決系統(tǒng)后門降級方式的缺點,我們可以將降級操作獨立到一個單獨的系統(tǒng)中,實現(xiàn)復(fù)雜的權(quán)限管理、批量操作等功能。

其基本架構(gòu)如下:

圖片圖片

2. 熔斷

熔斷是指按照規(guī)則停掉外部接口的訪問,防止某些外部接口故障導(dǎo)致自己的系統(tǒng)處理能力急劇下降或者出故障。

圖片圖片

熔斷和降級是兩個比較容易混淆的概念,因為單純從名字上看,好像都有禁止某個功能的意思。但它們的內(nèi)涵是不同的,因為降級的目的是應(yīng)對系統(tǒng)自身的故障,而熔斷的目的是應(yīng)對依賴的外部系統(tǒng)故障的情況。

假設(shè)一個這樣的場景:A服務(wù)的X功能依賴B服務(wù)的某個接口,當(dāng)B服務(wù)的接口響應(yīng)很慢的時候,A服務(wù)的X功能響應(yīng)肯定也會被拖慢,進一步導(dǎo)致A服務(wù)的線程都被卡在X功能處理上,于是A服務(wù)的其他功能都會被卡住或者響應(yīng)非常慢。

這時就需要熔斷機制了:A服務(wù)不再請求B服務(wù)的這個接口,A服務(wù)內(nèi)部只要發(fā)現(xiàn)是請求B服務(wù)的這個接口就立即返回錯誤,從而避免A服務(wù)整個被拖慢甚至拖死。

實現(xiàn)熔斷機制有兩個關(guān)鍵點:

一是需要有一個統(tǒng)一的API調(diào)用層,由API調(diào)用層來進行采樣或者統(tǒng)計。如果接口調(diào)用散落在代碼各處,就沒法進行統(tǒng)一處理了。

二是閾值的設(shè)計,例如1分鐘內(nèi)30%的請求響應(yīng)時間超過1秒就熔斷,這個策略中的“1分鐘”“30%”“1秒”都對最終的熔斷效果有影響。實踐中,一般都是先根據(jù)分析確定閾值,然后上線觀察效果,再進行調(diào)優(yōu)。

3. 限流

降級是從系統(tǒng)功能優(yōu)先級的角度考慮如何應(yīng)對故障,而限流則是從用戶訪問壓力的角度來考慮如何應(yīng)對故障。限流指只允許系統(tǒng)能夠承受的訪問量進來,超出系統(tǒng)訪問能力的請求將被丟棄。

雖然“丟棄”這個詞聽起來讓人不太舒服,但保證一部分請求能夠正常響應(yīng),總比全部請求都不能響應(yīng)要好得多。

限流一般都是系統(tǒng)內(nèi)實現(xiàn)的,常見的限流方式可以分為兩類:基于請求限流和基于資源限流。

3.1 基于請求限流

基于請求限流指從外部訪問的請求角度考慮限流,常見的方式有兩種。

第一種是限制總量,也就是限制某個指標(biāo)的累積上限,常見的是限制當(dāng)前系統(tǒng)服務(wù)的用戶總量,例如:某個直播間限制總用戶數(shù)上限為100萬,超過100萬后新的用戶無法進入;某個搶購活動商品數(shù)量只有100個,限制參與搶購的用戶上限為1萬個,1萬以后的用戶直接拒絕。

第二種是限制時間量,也就是限制一段時間內(nèi)某個指標(biāo)的上限,例如1分鐘內(nèi)只允許10000個用戶訪問;每秒請求峰值最高為10萬。

無論是限制總量還是限制時間量,共同的特點都是實現(xiàn)簡單,但在實踐中面臨的主要問題是比較難以找到合適的閾值。例如系統(tǒng)設(shè)定了1分鐘10000個用戶,但實際上6000個用戶的時候系統(tǒng)就扛不住了;或者達到1分鐘10000用戶后,其實系統(tǒng)壓力還不大,但此時已經(jīng)開始丟棄用戶訪問了。

即使找到了合適的閾值,基于請求限流還面臨硬件相關(guān)的問題。例如一臺32核的機器和64核的機器處理能力差別很大,閾值是不同的,可能有的技術(shù)人員以為簡單根據(jù)硬件指標(biāo)進行數(shù)學(xué)運算就可以得出來,實際上這樣是不可行的,64核的機器比32核的機器,業(yè)務(wù)處理性能并不是2倍的關(guān)系,可能是1.5倍,甚至可能是1.1倍。

為了找到合理的閾值,通常情況下可以采用性能壓測來確定閾值,但性能壓測也存在覆蓋場景有限的問題,可能出現(xiàn)某個性能壓測沒有覆蓋的功能導(dǎo)致系統(tǒng)壓力很大;另外一種方式是逐步優(yōu)化:先設(shè)定一個閾值然后上線觀察運行情況,發(fā)現(xiàn)不合理就調(diào)整閾值。

基于上述的分析,根據(jù)閾值來限制訪問量的方式更多的適應(yīng)于業(yè)務(wù)功能比較簡單的系統(tǒng),例如負(fù)載均衡系統(tǒng)、網(wǎng)關(guān)系統(tǒng)、搶購系統(tǒng)等。

3.2 基于資源限流

基于請求限流是從系統(tǒng)外部考慮的,而基于資源限流是從系統(tǒng)內(nèi)部考慮的,也就是找到系統(tǒng)內(nèi)部影響性能的關(guān)鍵資源,對其使用上限進行限制。常見的內(nèi)部資源包括連接數(shù)、文件句柄、線程數(shù)和請求隊列等。

例如,采用Netty來實現(xiàn)服務(wù)器,每個進來的請求都先放入一個隊列,業(yè)務(wù)線程再從隊列讀取請求進行處理,隊列長度最大值為10000,隊列滿了就拒絕后面的請求;也可以根據(jù)CPU的負(fù)載或者占用率進行限流,當(dāng)CPU的占用率超過80%的時候就開始拒絕新的請求。

基于資源限流相比基于請求限流能夠更加有效地反映當(dāng)前系統(tǒng)的壓力,但實際設(shè)計時也面臨兩個主要的難點:如何確定關(guān)鍵資源,以及如何確定關(guān)鍵資源的閾值。

通常情況下,這也是一個逐步調(diào)優(yōu)的過程:設(shè)計的時候先根據(jù)推斷選擇某個關(guān)鍵資源和閾值,然后測試驗證,再上線觀察,如果發(fā)現(xiàn)不合理,再進行優(yōu)化。

限流算法

為了更好地實現(xiàn)前面描述的各種限流方式,通常情況下我們會基于限流算法來設(shè)計方案。常見的限流算法有兩大類四小類,它們的實現(xiàn)原理和優(yōu)缺點各不相同,在實際設(shè)計的時候需要根據(jù)業(yè)務(wù)場景來選擇。

(1)時間窗

第一大類是時間窗算法,它會限制一定時間窗口內(nèi)的請求量或者資源消耗量,根據(jù)實現(xiàn)方式又可以細(xì)分為“固定時間窗”和“滑動時間窗”。

  • 固定時間窗

固定時間窗算法的實現(xiàn)原理是,統(tǒng)計固定時間周期內(nèi)的請求量或者資源消耗量,超過限額就會啟動限流,如下圖所示:

圖片圖片

它的優(yōu)點是實現(xiàn)簡單,缺點是存在臨界點問題。例如上圖中的紅藍兩點只間隔了短短10秒,期間的請求數(shù)卻已經(jīng)達到200,超過了算法規(guī)定的限額(1分鐘內(nèi)處理100)。但是因為這些請求分別來自兩個統(tǒng)計窗口,從單個窗口來看還沒有超出限額,所以并不會啟動限流,結(jié)果可能導(dǎo)致系統(tǒng)因為壓力過大而掛掉。

  • 滑動時間窗

為了解決臨界點問題,滑動時間窗算法應(yīng)運而生,它的實現(xiàn)原理是,兩個統(tǒng)計周期部分重疊,從而避免短時間內(nèi)的兩個統(tǒng)計點分屬不同的時間窗的情況,如下圖所示:

圖片圖片

總體上來看,滑動時間窗的限流效果要比固定時間窗更好,但是實現(xiàn)也會稍微復(fù)雜一些。

(2)桶算法

第二大類是桶算法,用一個虛擬的“桶”來臨時存儲一些東西。根據(jù)桶里面放的東西,又可以細(xì)分為“漏桶”和“令牌桶”。

  • 漏桶

漏桶算法的實現(xiàn)原理是,將請求放入“桶”(消息隊列等),業(yè)務(wù)處理單元(線程、進程和應(yīng)用等)從桶里拿請求處理,桶滿則丟棄新的請求,如下圖所示:

圖片圖片


我們可以看到漏桶算法的三個關(guān)鍵實現(xiàn)點:

  • 流入速率不固定:可能瞬間流入非常多的請求,例如0點簽到、整點秒殺。
  • 勻速(極速)流出:這是理解漏桶算法的關(guān)鍵,也就是說即使大量請求進入了漏桶,但是從漏桶流出的速度是勻速的,速度的最大值就是系統(tǒng)的極限處理速度(對應(yīng)圖中的“極速”)。這樣就保證了系統(tǒng)在收到海量請求的時候不被壓垮,這是第一層的保護措施。需要注意的是:如果漏桶沒有堆積,那么流出速度就等于流入速度,這個時候流出速度就不是勻速的。
  • 桶滿則丟棄請求:這是第二層保護措施,也就是說漏桶不是無限容量,而是有限容量,例如漏桶最多存儲100萬個請求,桶滿了則直接丟棄后面的請求。

漏桶算法的技術(shù)本質(zhì)是總量控制,桶大小是設(shè)計關(guān)鍵,具體的優(yōu)缺點如下:

  • 突發(fā)大量流量時丟棄的請求較少,因為漏桶本身有緩存請求的作用。
  • 桶大小動態(tài)調(diào)整比較困難(例如 Java BlockingQueue),需要不斷的嘗試才能找到符合業(yè)務(wù)需求的最佳桶大小。
  • 無法精確控制流出速度,也就是業(yè)務(wù)的處理速度。

漏桶算法主要適用于瞬時高并發(fā)流量的場景(例如剛才提到的0點簽到、整點秒殺等)。在短短幾分鐘內(nèi)涌入大量請求時,為了更好的業(yè)務(wù)效果和用戶體驗,即使處理慢一些,也要做到盡量不丟棄用戶請求。

  • 令牌桶算法

令牌桶算法和漏桶算法的不同之處在于,桶中放入的不是請求,而是“令牌”,這個令牌就是業(yè)務(wù)處理前需要拿到的“許可證”。也就是說,當(dāng)系統(tǒng)收到一個請求時,先要到令牌桶里面拿“令牌”,拿到令牌才能進一步處理,拿不到就要丟棄請求。

它的實現(xiàn)原理是如下圖所示:

圖片圖片

我們可以看到令牌桶算法的三個關(guān)鍵設(shè)計點:

  • 有一個處理單元往桶里面放令牌,放的速率是可以控制的。
  • 桶里面可以累積一定數(shù)量的令牌,當(dāng)突發(fā)流量過來的時候,因為桶里面有累積的令牌,此時的業(yè)務(wù)處理速度會超過令牌放入的速度。
  • 如果令牌不足,即使系統(tǒng)有能力處理,也會丟棄請求。

令牌桶算法的技術(shù)本質(zhì)是速率控制,令牌產(chǎn)生的速率是設(shè)計關(guān)鍵,具體的優(yōu)缺點如下:

  • 可以動態(tài)調(diào)整處理速率,實現(xiàn)更加靈活。
  • 突發(fā)大量流量的時候可能丟棄很多請求,因為令牌桶不能累積太多令牌。
  • 實現(xiàn)相對復(fù)雜。

令牌桶算法主要適用于兩種典型的場景,一種是需要控制訪問第三方服務(wù)的速度,防止把下游壓垮,例如支付寶需要控制訪問銀行接口的速率;另一種是需要控制自己的處理速度,防止過載,例如壓測結(jié)果顯示系統(tǒng)最大處理TPS是100,那么就可以用令牌桶來限制最大的處理速度。

剛才介紹漏桶算法的時候我提到漏桶算法可以應(yīng)對瞬時高并發(fā)流量,現(xiàn)在介紹令牌桶算法的時候,我又說令牌桶允許突發(fā)流量。

你可能會問,這兩種說法好像差不多啊,它們到底有什么區(qū)別,到底誰更適合做秒殺呢?

其實,令牌桶的“允許突發(fā)”實際上只是“允許一定程度的突發(fā)”,比如系統(tǒng)處理能力是每秒100 TPS,突發(fā)到120 TPS是可以的,但如果突發(fā)到1000 TPS的話,系統(tǒng)大概率就被壓垮了。所以處理秒殺時高并發(fā)流量,還是得用漏桶算法。

令牌桶的算法原本是用于網(wǎng)絡(luò)設(shè)備控制傳輸速度的,而且它控制的目的是保證一段時間內(nèi)的平均傳輸速度。之所以說令牌桶適合突發(fā)流量,是指在網(wǎng)絡(luò)傳輸?shù)臅r候,可以允許某段時間內(nèi)(一般就幾秒)超過平均傳輸速率,這在網(wǎng)絡(luò)環(huán)境下常見的情況就是“網(wǎng)絡(luò)抖動”。

但這個短時間的突發(fā)流量并不會導(dǎo)致雪崩效應(yīng),網(wǎng)絡(luò)設(shè)備也能夠處理得過來。對應(yīng)到令牌桶應(yīng)用到業(yè)務(wù)處理的場景,就要求即使有突發(fā)流量來了,系統(tǒng)自己或者下游系統(tǒng)要真的能夠處理的過來,否則令牌桶允許突發(fā)流量進來,結(jié)果系統(tǒng)或者下游處理不了,那還是會被壓垮。

因此,令牌桶在實際設(shè)計的時候,桶大小不能像漏桶那樣設(shè)計很大,需要根據(jù)系統(tǒng)的處理能力來進行仔細(xì)的估算。例如,漏桶算法的桶容量可以設(shè)計為100萬,但是一個每秒30 TPS的令牌桶,桶的容量可能只能設(shè)計成40左右。海外有的銀行給移動錢包提供的接口TPS上限是30,壓測到了40就真的掛了。

4. 排隊

排隊實際上是限流的一個變種,限流是直接拒絕用戶,排隊是讓用戶等待一段時間,全世界最有名的排隊當(dāng)屬12306網(wǎng)站排隊了。

排隊雖然沒有直接拒絕用戶,但用戶等了很長時間后進入系統(tǒng),體驗并不一定比限流好。

由于排隊需要臨時緩存大量的業(yè)務(wù)請求,單個系統(tǒng)內(nèi)部無法緩存這么多數(shù)據(jù),一般情況下,排隊需要用獨立的系統(tǒng)去實現(xiàn),例如使用Kafka這類消息隊列來緩存用戶請求。

下圖是1號店的“雙11”秒殺排隊系統(tǒng)架構(gòu):

圖片圖片

它的基本實現(xiàn)摘錄如下:

【排隊模塊】 負(fù)責(zé)接收用戶的搶購請求,將請求以先入先出的方式保存下來。每一個參加秒殺活動的商品保存一個隊列,隊列的大小可以根據(jù)參與秒殺的商品數(shù)量(或加點余量)自行定義。

【調(diào)度模塊】 負(fù)責(zé)排隊模塊到服務(wù)模塊的動態(tài)調(diào)度,不斷檢查服務(wù)模塊,一旦處理能力有空閑,就從排隊隊列頭上把用戶訪問請求調(diào)入服務(wù)模塊,并負(fù)責(zé)向服務(wù)模塊分發(fā)請求。這里調(diào)度模塊扮演一個中介的角色,但不只是傳遞請求而已,它還擔(dān)負(fù)著調(diào)節(jié)系統(tǒng)處理能力的重任。我們可以根據(jù)服務(wù)模塊的實際處理能力,動態(tài)調(diào)節(jié)向排隊系統(tǒng)拉取請求的速度。

【服務(wù)模塊】 負(fù)責(zé)調(diào)用真正業(yè)務(wù)來處理服務(wù),并返回處理結(jié)果,調(diào)用排隊模塊的接口回寫業(yè)務(wù)處理結(jié)果。

小結(jié)

今天我為你講了接口級故障的四種應(yīng)對方法,分別是降級、熔斷、限流和排隊,希望對你有所幫助。

方法

實現(xiàn)原理

場景

案例

降級

停掉故障接口,收到接口請求后直接返回錯誤,避免不重要的接口故障后產(chǎn)生鏈?zhǔn)椒磻?yīng),導(dǎo)致系統(tǒng)整體故障

應(yīng)對系統(tǒng)自身的接口故障

論壇可以降級為只能看帖子,不能發(fā)帖子;

淘寶雙十一的時候?qū)ⅰ邦I(lǐng)淘金幣”降級

熔斷

按照規(guī)則停掉外部接口的訪問,防止某些外部接口故障導(dǎo)致自己的系統(tǒng)處理能力急劇下降或者出故障

依賴的外部系統(tǒng)的接口故障

支付寶雙十一訪問某銀行的支付接口,一分鐘內(nèi)失敗率超過設(shè)定的閾值,接下來10分鐘內(nèi)不再訪問此接口,10分鐘后再試

限流

只允許系統(tǒng)能夠承受的訪問量進來,超出系統(tǒng)訪問能力的請求將被丟棄,防止系統(tǒng)被壓垮

應(yīng)對訪問壓力過大的情況

0點簽到、整點秒殺;

支付寶控制訪問銀行接口的速率

排隊

盡量接收用戶的請求,但是沒有立即處理,而是先將用戶請求緩存起來,需要用戶等待一段時間才會真正開始處理

應(yīng)對用戶訪問壓力過大的情況,相比限流可以有更好的用戶體驗,但實現(xiàn)更復(fù)雜

12306購票;

1號店雙一秒殺


責(zé)任編輯:武曉燕 來源: 一安未來
相關(guān)推薦

2024-05-06 08:43:00

2018-06-05 09:31:01

微博緩存架構(gòu)設(shè)計

2025-03-06 01:00:55

架構(gòu)推送服務(wù)編程語言

2024-08-16 14:01:00

2016-01-11 11:20:43

2015-06-02 04:17:44

架構(gòu)設(shè)計審架構(gòu)設(shè)計說明書

2018-05-17 10:10:17

架構(gòu)設(shè)計優(yōu)化

2022-04-11 09:15:00

前端開發(fā)技術(shù)

2015-06-02 04:34:05

架構(gòu)設(shè)計

2015-10-13 10:06:41

數(shù)據(jù)遷移技術(shù)選型架構(gòu)設(shè)計

2009-07-06 10:36:41

敏捷開發(fā)

2021-11-08 06:57:35

Redis架構(gòu)設(shè)計

2017-09-27 13:56:58

微服務(wù)架構(gòu)故障網(wǎng)絡(luò)

2022-05-24 09:30:00

消息吞吐車聯(lián)網(wǎng)平臺車聯(lián)網(wǎng)

2009-08-25 13:25:00

Java企業(yè)級應(yīng)用架構(gòu)分布式結(jié)構(gòu)

2013-05-27 10:58:28

Tumblr架構(gòu)設(shè)計雅虎收購

2017-05-17 14:51:31

DNS架構(gòu)負(fù)載均衡

2022-05-18 10:07:29

EMQ車聯(lián)網(wǎng)MQTT

2024-05-27 08:32:45

2024-11-27 13:01:22

應(yīng)用層領(lǐng)域?qū)?/a>對接層
點贊
收藏

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