能讓程序員漲薪 5K 的 Hystrix 核心工作原理,你真的不打算學嗎?
Hystrix 的核心工作原理
Hystrix 的本質作用是當系統資源過載(Over Load Control)時提供服務狀態保護機制,包括下面四個方面。
-
熔斷:當失敗率達到閾值時自動觸發降級(如因網絡故障或超時造成的失敗率高),熔斷器觸發的快速失敗會進行快速恢復。
-
隔離(線程池隔離和信號量隔離):限制調用分佈式服務的資源使用,某一個調用的服務出現問題不會影響其他調用。
-
降級:超時降級、資源不足時(線程或信號量)降級,降級後可以配合降級接口返回託底數據,做到優雅降級。
-
緩存:提供了請求緩存、請求合併的實現方法。
Hystrix——熔斷
熔斷器的原理很簡單,可以實現快速失敗,如果它在一段時間內偵測到許多類似的錯誤,會強迫其以後的多個調用快速失敗,不再訪問遠程服務器,從而防止應用程序不斷地嘗試執行可能會失敗的操作,使得應用程序繼續執行而不用等待修正錯誤,或者浪費 CPU 時間去等到長時間的超時產生。熔斷器也可以使應用程序診斷錯誤是否已經修正,如果已經修正,應用程序會再次嘗試調用操作。
熔斷器就像是那些容易導致錯誤的操作的一種代理。這種代理能夠記錄最近調用發生錯誤的次數,然後決定允許操作繼續或者立即返回錯誤。熔斷器開關相互轉換的邏輯如下圖所示。
Hystrix 中的熔斷器(Circuit Breaker)也起到這樣的作用,Hystrix 在運行過程中會向每個 CommandKey 對應的熔斷器報告成功、失敗、超時和拒絕的狀態,熔斷器維護並計算統計的數據,根據這些統計信息來確定是否打開。如果打開,後續的請求都會被截斷(不再執行 run 方法裏的內容,直接執行 fallback 方法裏的內容)。然後隔一段時間(默認是 5s),嘗試半開,放一部分請求進來,相當於對依賴服務進行一次健康檢查,如果服務沒問題,熔斷器關閉,隨後完全恢復調用。
Hystrix——隔離
對於微服務系統來說,一個從客戶端發來的 HTTP 請求往往途徑衆多微服務,在處於高流量狀態下,如果其中一個服務器資源出現飽和狀態,就會影響上游系統。如下圖所示,Hystrix 可以將服務調用包裹在 HystrixCommand 中,每一個 HystrixCommand 都維護着一個線程池,從而隔離服務,當一個服務產生延遲時,其 “吞噬” 的資源也只會限定在該 HystrixCommand 內(比如至多隻會佔用 N 個線程資源),而不會對全局造成影響。
Hystrix 的隔離主要是爲每個依賴組件提供一個隔離的線程環境,有兩種隔離模式。
-
線程池隔離模式:使用一個線程池來存儲當前的請求。線程池對請求做處理,設置任務返回處理超時時間,堆積的請求堆積入線程池隊列。這種方式需要爲每個依賴的服務申請線程池,有一定的資源消耗,好處是可以應對突發流量(流量洪峯來臨時,處理不完可將數據存儲到線程池裏慢慢處理)。
-
信號量隔離模式:使用一個原子計數器(或信號量)來記錄當前有多少個線程在運行,請求到來時先判斷計數器的數值,若超過設置的最大線程個數,則丟棄該類型的新請求,若不超過,則執行計數操作,請求到來計數器 + 1,請求返回計數器 - 1。這種方式是嚴格的控制線程且立即返回模式,無法應對突發流量(流量洪峯來臨時,處理的線程超過數量,其他的請求會直接返回,不繼續去請求依賴的服務)。
兩種隔離模式的主要區別如下表所示。
Hystrix 隔離策略相關的參數如下。
-
execution.isolation.strategy=THREAD|SEMAPHORE:設置線程或信號量隔離模式。
-
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:設置隔離模式的超時時間,默認值是 1000ms。
-
execution.isolation.semaphore.maxConcurrentRequests :設置在使用時允許到 HystrixCommand.run 方法的最大請求數,默認值是 10。
-
execution.timeout.enabled:設置 HystrixCommand.run 方法執行時是否開啓超時設置,默認開啓。
-
execution.isolation.thread.interruptOnTimeout:發生超時時是否中斷 HystrixCommand.run 方法,默認是 true。
-
execution.isolation.thread.interruptOnCancel:取消時是否中斷 HystrixCommand.run 方法,默認是 false。
Hystrix——降級
所謂降級,就是指在 Hystrix 執行非核心鏈路功能失敗的情況下,我們如何處理,比如我們返回默認值等。如果我們要回退或者降級處理 , 代 碼 上 需 要 實 現
HystrixCommand.getFallback 方 法 或 者 HystrixObservableCommand 方法。
Netflix 的 Hystrix 對微服務降級處理實現提供兩種方式:
-
通過添加註解 @HystrixCommand 方式來實現。
-
通過繼承 HystrixCommand 類來實現。
- 使用 @HystrixCommand 註解實現服務降級
使用註解可以最小限度地侵入代碼,可以快速讓原來的功能支持服 務 降 級 , 使 用 時 僅 需 在 要 進 行 服 務 降 級 處 理 的 方 法 上 增 加 @HystrixCommand 註解即可,並通過 fallbackMethod 屬性設置在降級處理時所使用的方法,然後在降級方法中實現服務降級處理。需要注意:通過 fallbackMethod 屬性所指定的方法要與原方法具有相同的方法簽名,否則降級會失敗。下面是 @HystrixCommand 的參數說明。
-
groupKey:設置 HystrixCommand 分組的名稱。
-
commandKey:設置 HystrixCommand 的名稱。
-
threadPollKey:設置 HystrixCommand 執行線程池的名稱。
-
fallbackMethod:設置 HystrixCommand 服務降級所使用的方法
名稱,注意該方法需要與原方法定義在同一個類中,並且方法簽名也要一致。
-
commandProperties:設置 HystrixCommand 屬性,例如斷路器失敗百分比、斷路器時間容器大小等。
-
ignoreException:設置 HystrixCommand 執行服務降級處理時需要忽略的異常,當出現異常時不會執行服務降級處理。
-
observableExecutionMode :設 置 HystrixCommand 執 行 的 方式。
-
defaultFallback:設置 HystrixCommand 默認的服務降級處理方 法 , 如 果 同 時 設 定 fallbackMethod 屬 性 , 會 優 先 使 用 fallbackMethod 屬性所指定的方法。該屬性所指定的方法沒有參數,需要注意返回值與原方法返回值的兼容性。
- 繼承 HystrixCommand 類實現服務降級
除使用註解方式來完成服務降級實現外,Hystrix 還提供了兩個對象 來 支 持 服 務 降 級 實 現 處 理 :HystrixCommand 和 HystrixObserableCommand 。如 果 繼 承 HystrixCommand 則 需 要 實 現 getFallback 方法,代碼如下:
HystrixObserableCommand 用於所依賴服務返回多個操作結果的時候,在實現服務降級時,如果是繼承 HystrixObserableCommand,則需要實現 resumeWithFallback 方法,代碼如下。
Hystrix——緩存
Hystrix 有兩種方式來應對高併發場景,分別是請求緩存與請求合併緩存。請求緩存是在同一請求多次訪問中保證只調用一次這個服務提供者的接口,同一請求第一次的結果會被緩存,保證同一請求多次訪問返回結果相同。
Hystrix 的緩存實現方式主要有兩種:繼承方式和註解方式,用得比較多的方式是註解方式,因爲註解方式開發快而且相對簡單,如下表所示。
- 使用 @CacheResult 開啓請求緩存功能
- 使用 CacheKey 開啓緩存
- 通過 @CacheRemove 註解來實現失效緩存清理功能
Hystrix 的工作流程
Hystrix 使用 RxJava 作爲響應式的編程框架。這裏我們簡單介紹一下 Hystrix 的工作流程,一個簡化版本的 Hystrix 執行流程如下圖所示。
首先,構造一個 HystrixCommand 或 HystrixObservableCommand 對象。
- 如果期望依賴項返回單個響應,則構造一個 HystrixCommand 對象,代碼如下:
- 如果期望依賴項返回發出響應的可觀察對象,則構造一個 HystrixObservableComman 對象,代碼如下:
有 4 種方法可以執行 Hystrix 命令(前兩種方法只適用於簡單的 HystrixCommand 對象,不適用於 HystrixObservableCommand 對象)。
-
execute:該方法與 queue 方法以相同的方式獲取一個 Future 對象,然後在這個 Future 上調用 get 方法來獲取可觀察對象發出的單個值。
-
queue:該方法將可觀察對象轉換爲 BlockingObservable 對象,以便將其轉換爲 Future 對象,然後返回此 Future 對象。
-
observe:該方法可以立即訂閱可觀察對象,並開始執行命令的流。返回一個可觀察對象,當訂閱該對象時,它將重新產生結果並通知訂閱者。
-
toObservable:該方法返回的可觀察值不變,需要訂閱後才能真正開始執行命令流程。
下面是 Hystrix 的具體執行邏輯。
- 構造 Hystrix 命令
構造一個 HystrixCommand 或 HystrixObservableCommand 對象,用於封裝請求並在構造方法中配置請求被執行需要的參數。
- 執行 Hystrix 命令
根據上文中提供的 4 種方式執行命令。
- 判斷是否緩存了響應
如果你爲命令啓用了請求緩存,並且在緩存中命中了可用請求的響應,則緩存的響應將立即以可觀察到的形式返回。
- 判斷熔斷電路是否打開
當執行命令時,Hystrix 將與斷路器一起檢查熔斷電路是否打開。
如果熔斷電路打開,那麼 Hystrix 將不執行命令並回退。如果熔斷電路關閉,則繼續執行,檢查是否有可用的容量來運行命令。
- 線程池、隊列、信號量是否已滿
如果與命令關聯的線程池和隊列(或信號量,如果不在線程中運行)已滿,那麼 Hystrix 將不執行命令,執行邏輯跳轉到第 7 步。
- 計算電路健康狀態
執行
HystrixObservableCommand.construct 或 HystrixCommand.run 方法,Hystrix 向斷路器報告成功、失敗、拒絕或超時,如果執行邏輯失敗或者超,則執行邏輯跳轉第 7 步;否則執行邏輯跳轉到第 8 步;
- 回退
Hystrix 試圖恢復你的回滾命令,並執行回退邏輯或者 fallback 備用邏輯。
- 返回成功的響應如果 Hystrix 命令成功,它將以可觀察到的形式返回響應給調用者。
來源: https://www.toutiao.com/a7046378769019339297/?log_from=bb0000b450587_1641259982976
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/TGXpdQbKMUksu7mof8-kYA