天天看點

Hystrix熔斷器第 3 節Hystrix熔斷器

第 3 節Hystrix熔斷器

屬于一種容錯機制

3.1 微服務中的雪崩效應

當山坡積雪内部的内聚力抗拒不了它所受到的重力拉引時,便向下滑動,引起大量雪體崩塌,人們

把這種自然現象稱作雪崩。

微服務中,一個請求可能需要多個微服務接口才能實作,會形成複雜的調用鍊路。

服務雪崩效應:是一種因“服務提供者的不可用”(原因)導緻“服務調用者不可用”(結果),并将不可用逐漸放大的現象。

Hystrix熔斷器第 3 節Hystrix熔斷器
Hystrix熔斷器第 3 節Hystrix熔斷器
Hystrix熔斷器第 3 節Hystrix熔斷器
Hystrix熔斷器第 3 節Hystrix熔斷器
Hystrix熔斷器第 3 節Hystrix熔斷器

扇入:代表着該微服務被調用的次數,扇入大,說明該子產品複用性好

扇出:該微服務調用其他微服務的個數,扇出大,說明業務邏輯複雜

扇入大是一個好事,扇出大不一定是好事

在微服務架構中,一個應用可能會有多個微服務組成,微服務之間的資料互動通過遠端過程調用完成。這就帶來一個問題,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其它的微服務,這就是所謂的“扇出”。如果扇出的鍊路上某個微服務的調用響應時間過長或者不可用,對微服務A的調用就會占用越來越多的系統資源,進而引起系統崩潰,所謂的“雪崩效應”。

如圖中所示,最下遊商品微服務響應時間過長,大量請求阻塞,大量線程不會釋放,會導緻伺服器資源耗盡,最終導緻上遊服務甚至整個系統癱瘓。

形成原因:

服務雪崩的過程可以分為三個階段:

1. 服務提供者不可用

2. 重試加大請求流量

3. 服務調用者不可用

服務雪崩的每個階段都可能由不同的原因造成:

Hystrix熔斷器第 3 節Hystrix熔斷器

3.2 雪崩效應解決方案

從可用性可靠性着想,為防止系統的整體緩慢甚至崩潰,采用的技術手段;

下面,我們介紹三種技術手段應對微服務中的雪崩效應,這三種手段都是從系統可用性、可靠性角度出發,盡量防止系統整體緩慢甚至癱瘓。

服務熔斷

熔斷機制是應對雪崩效應的一種微服務鍊路保護機制。我們在各種場景下都會接觸到熔斷這兩個字。高壓電路中,如果某個地方的電壓過高,熔斷器就會熔斷,對電路進行保護。股票交易中,如果股票指數過高,也會采用熔斷機制,暫停股票的交易。同樣,在微服務架構中,熔斷機制也是起着類似的作用。當扇對外連結路的某個微服務不可用或者響應時間太長時,熔斷該節點微服務的調用,進行服務的降級,快速傳回錯誤的響應資訊。當檢測到該節點微服務調用響應正常後,恢複調用鍊路。

注意:

1)服務熔斷重點在“斷”,切斷對下遊服務的調用

2)服務熔斷和服務降級往往是一起使用的,Hystrix就是這樣。

服務降級

通俗講就是整體資源不夠用了,先将一些不關緊的服務停掉(調用我的時候,給你傳回一個預留的值,也叫做兜底資料),待渡過難關高峰過去,再把那些服務打開。服務降級一般是從整體考慮,就是當某個服務熔斷之後,伺服器将不再被調用,此刻用戶端可以自己準備一個本地的fallback回調,傳回一個預設值,這樣做,雖然服務水準下降,但好歹可用,比直接挂掉要強。

服務限流 服務降級是當服務出問題或者影響到核心流程的性能時,暫時将服務屏蔽掉,待高峰或者問題解決後再打開;但是有些場景并不能用服務降級來解決,比如秒殺業務這樣的核心功能,這個時候可以結合服務限流來限制這些場景的并發/請求量限流措施也很多,比如

  • 限制總并發數(比如資料庫連接配接池、線程池)
  • 限制瞬時并發數(如nginx限制瞬時并發連接配接數)
  • 限制時間視窗内的平均速率(如Guava的RateLimiter、nginx的limit_req子產品,限制每秒的平均速率)
  • 限制遠端接口調用速率、限制MQ的消費速率等

3.3 Hystrix簡介

[來自官網]Hystrix(豪豬),宣言“defend your application”是由Netflflix開源的一個延遲和容錯庫,用于隔離通路遠端系統、服務或者第三方庫,防止級聯失敗,進而提升系統的可用性與容錯性。Hystrix主要通過以下幾點實作延遲和容錯。

  • 包裹請求:使用HystrixCommand包裹對依賴的調用邏輯。 頁面靜态化微服務方法(@HystrixCommand 添加Hystrix控制)
  • 跳閘機制:當某服務的錯誤率超過一定的門檻值時,Hystrix可以跳閘,停止請求該服務一段時間。
  • 資源隔離:Hystrix為每個依賴都維護了一個小型的線程池(艙壁模式)。如果該線程池已滿, 發往該

依賴的請求就被立即拒絕,而不是排隊等待,進而加速失敗判定。

  • 監控:Hystrix可以近乎實時地監控運作名額和配置的變化,例如成功、失敗、逾時、以及被拒絕的請求等。
  • 回退機制:當請求失敗、逾時、被拒絕,或當斷路器打開時,執行回退邏輯。回退邏輯由開發人員自行提供,例如傳回一個預設值。
  • 自我修複:斷路器打開一段時間後,會自動進入“半開”狀态(探測服務是否可用,如還是不可用,再次退回打開狀态)。

3.4 Hystrix艙壁模式

即:線程池隔離政策

如果不進行任何設定,所有熔斷方法使用一個Hystrix線程池(10個線程),那麼這樣的話會導緻問題,

這個問題并不是扇對外連結路微服務不可用導緻的,而是我們的線程機制導緻的,如果方法A的請求把10個

線程都用了,方法2請求處理的時候壓根都沒法去通路B,因為沒有線程可用,并不是B服務不可用。

Hystrix熔斷器第 3 節Hystrix熔斷器

為了避免問題服務請求過多導緻正常服務無法通路,Hystrix 不是采用增加線程數,而是單獨的為每一個

控制方法建立一個線程池的方式,這種模式叫做“艙壁模式",也是線程隔離的手段。

3.5 Hystrix工作流程與進階應用

Hystrix熔斷器第 3 節Hystrix熔斷器

1)當調用出現問題時,開啟一個時間窗(10s)

2)在這個時間窗内,統計調用次數是否達到最小請求數?

如果沒有達到,則重置統計資訊,回到第1步

如果達到了,則統計失敗的請求數占所有請求數的百分比,是否達到門檻值?

如果達到,則跳閘(不再請求對應服務)

如果沒有達到,則重置統計資訊,回到第1步

3)如果跳閘,則會開啟一個活動視窗(預設5s),每隔5s,Hystrix會讓一個請求通過,到達那個問題服務,看是否調用成功,如果成功,重置斷路器回到第1步,如果失敗,回到第3步

@HystrixCommand(
            //隻有是在@HystrixCommand中定義了threadPoolKey,就意味着開啟了艙壁模式(線程隔離),該方法就         會自己維護一個線程池。
            threadPoolKey = "getProductServerPort2", //預設所有的請求共同維護一個線程池,實際開發:每個方法維護一個線程池
            //每一個屬性對應的都是一個HystrixProperty
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "1"),//并發線程數
                    @HystrixProperty(name = "maxQueueSize", value = "20")//預設線程隊列值是-1,預設不開啟
            },
            //逾時時間的設定
            commandProperties = {
                    //設定請求的逾時時間,一旦請求超過此時間那麼都按照逾時處理,預設逾時時間是1S
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
            }
    )
           

我們上述通過注解進行的配置也可以配置在配置檔案中:

Hystrix熔斷器第 3 節Hystrix熔斷器

基于springboot的健康檢查觀察跳閘狀态(自動投遞微服務暴露健康檢查細節)

Hystrix熔斷器第 3 節Hystrix熔斷器

Hystrix 線程池隊列配置生産案例:

  有一次在生産環境,突然出現了很多筆還款單被挂起,後來排查原因,發現是内部系統調用時出現了Hystrix調用異常。在開發過程中,因為核心線程數設定的比較大,沒有出現這種異常。放到了測試環境,偶爾有出現這種情況。

  後來調整maxQueueSize屬性,确實有所改善。可沒想到在生産環境跑了一段時間後卻又出現這種了情況,此時我第一想法就是去檢視maxQueueSize屬性,可是maxQueueSize屬性是設定值了。

  當時就比較納悶了,為什麼maxQueueSize屬性不起作用,後來通過檢視官方文檔發現Hystrix還有一個queueSizeRejectionThreshold屬性,這個屬性是控制隊列最大門檻值的,而Hystrix預設隻配置了5個,是以就算我們把maxQueueSize的值設定再大,也是不起作用的。兩個屬性必須同時配置

Hystrix熔斷器第 3 節Hystrix熔斷器

正确的配置案例:

  将核心線程數調低,最大隊列數和隊列拒絕門檻值的值都設定大一點:

Hystrix熔斷器第 3 節Hystrix熔斷器