天天看點

微服務架構 — 服務治理 — 服務限流、服務降級、服務熔斷

目錄

服務限流

服務降級

服務熔斷

c ⇄ s 的異常問題:c 的請求太多,超出 s 的服務能力,導緻 s 不可用。例如:dos 攻擊,企圖耗盡被攻擊對象的資源,讓目标系統無法響應直至崩潰。是以,s 需要能夠進行自我保護,例如:s 對 c 限流,保護 s 的服務資源。

限流通常在網關或網絡層面實施。對各類請求設定最高的 qps 門檻值,當請求高于門檻值時直接阻斷。常用的限流算法有滑動計數,漏鬥限流和令牌桶限流三種。

滑動計數限流:按時間片(比如 1 秒)定義滑動視窗,計數器記錄目前視窗的請求次數,達到門檻值就限流,視窗滑動後計數器歸零。可采用循環隊列資料結構實作。

漏鬥限流:維護一個隊列,所有請求進隊列,按 fifo 服務,隊滿溢出則丢棄請求。

令牌桶限流:按固定速率往桶中存入令牌,服務前先從桶中取令牌,取到令牌才服務。

限流政策有很多,最簡單的比如當機關時間内請求數過多時,丢棄多餘的請求。另外,也可以考慮分區限流。僅拒絕來自産生大量請求的服務的請求。例如:商品服務和訂單服務都需要通路促銷服務,商品服務由于代碼問題發起了大量請求,促銷服務則隻限制來自商品服務的請求,來自訂單服務的請求則正常響應。

微服務架構 — 服務治理 — 服務限流、服務降級、服務熔斷

c ⇄ s 的異常問題:s 自身出現異常,或者由于資源有限需要對部分 c 請求故意表現為異常(類似限流),為了不影響其他服務功能,主動關閉服務的一些功能。

當下遊服務停止工作後,如果該服務并非核心業務,則上遊服務應該降級,以保證核心業務不中斷。比如:網上超市下單界面有一個推薦商品湊單的功能,當推薦子產品挂了後,下單功能不能一起挂掉,隻需要暫時關閉推薦功能即可。

簡而言之,降級類似于把部分代碼注釋掉,犧牲部分功能。這要求 s 在實作時,需要具備感覺異常的能力,并對關鍵邏輯實作開關控制。實際場景中,對異常的感覺通常由熔斷器實作。

c ⇄ s 的異常問題:當 c 發現 s 出現異常(比如:大量逾時),由 c 主動出擊,暫停對 s 的請求。

當一個服務因為各種原因停止響應時,調用方通常會等待一段時間,然後逾時或者收到錯誤傳回。如果調用鍊路比較長,可能會導緻請求堆積,整條鍊路占用大量資源一直在等待下遊響應。是以當多次通路一個服務失敗時,應熔斷,标記該服務已停止工作,直接傳回錯誤。直至該服務恢複正常後再重建立立連接配接。

c 對 s 熔斷後,那麼原本需要調用 s 實作的邏輯怎麼辦呢?c 可以使用 mock 資料、緩存資料、預設資料等替代,或者幹脆就是抛異常傳回錯誤資訊。此時,如果 c 也是一個服務,它相當于做了服務降級。是以我們經常看到服務熔斷和服務降級一起出現(hystrix 的斷路器在實作時就是把熔斷和降級方案打包實作的)。但本質上它們不是一回事,降級發生在 s,熔斷發生在 c。之是以配合實作,是因為許多微服務子產品同時承擔 c 和 s 兩種角色。

微服務架構 — 服務治理 — 服務限流、服務降級、服務熔斷

服務熔斷的設計有兩個關鍵點:

判斷何時熔斷:通常使用無鎖循環隊列計數來實作。c 對每次請求 s 的正常、異常(失敗、拒絕、逾時)傳回計數,當異常傳回次數超過設定門檻值時進行熔斷。

何時從熔斷狀态恢複:處于熔斷狀态時,c 每隔一段時間(比如 5 秒),允許部分請求通過,若這部分請求正常傳回,就恢複熔斷。