springcloud实践之断路器:Hystrix原理和解构
服務雪崩效應
基礎服務的故障導致級聯故障,進而造成了整個分布式系統的不可用,這種現象被稱為服務雪崩效應。服務雪崩效應描述的是一種因服務提供者的不可用導致服務消費者的不可用,并將不可用逐漸放大的過程。
服務雪崩效應形成的原因
- 硬件故障
- 程序Bug
- 緩存擊穿
- 用戶大量請求
- 用戶重試
- 代碼邏輯重試
- 同步等待造成的資源耗盡
服務雪崩的應對策略
- 網關限流
- 用戶交互限流
- 關閉重試
- 緩存預加載
- 同步改為異步刷新
- AWS的auto scaling
- 資源隔離
- 對依賴服務進行分類
- 不可用服務的調用快速失敗
打鐵還需自身硬,本篇文章不展開論述各種應對策略,主要探討微服務自身如何來保護自己,避免奔潰?即微服務如何進行容錯設計?
容量設計在生活中經常見到,每家每戶都有保險絲,用電超負荷了,就會跳閘。微服務的容錯組件Hystrix就吸收了這些思想。
Hystrix
Hystrix [h?st'r?ks]的中文含義是豪豬科動物,如下圖所示, 因其背上長滿了刺,而擁有自我保護能力.
Netflix的 Hystrix 是一個幫助解決分布式系統交互時超時處理和容錯的類庫, 它同樣擁有保護系統的能力.
?
Hystrix如何保護我們的應用?
How Does Hystrix Accomplish Its Goals?
下面主要展開講述資源隔離、服務降級、服務熔斷、請求合并以及服務監(jiān)控等功能特性。
資源隔離
資源隔離--設計思想來源
貨船為了進行防止漏水和火災等風險的擴散,會將貨倉分隔為多個隔離區(qū)域,這種資源隔離減少風險的方式被稱為:Bulkheads(艙壁隔離模式).
官網關于資源隔離的舉例如下:
?
兩種資源隔離模式
(1)線程池隔離模式:使用一個線程池來存儲當前的請求,線程池對請求作處理,設置任務返回處理超時時間,堆積的請求堆積入線程池隊列。這種方式需要為每個依賴的服務申請線程池,有一定的資源消耗,好處是可以應對突發(fā)流量(流量洪峰來臨時,處理不完可將數據存儲到線程池隊里慢慢處理)
(2)信號量隔離模式:使用一個原子計數器(或信號量)來記錄當前有多少個線程在運行,請求來先判斷計數器的數值,若超過設置的最大線程個數則丟棄改類型的新請求,若不超過則執(zhí)行計數操作請求來計數器+1,請求返回計數器-1。這種方式是嚴格的控制線程且立即返回模式,無法應對突發(fā)流量(流量洪峰來臨時,處理的線程超過數量,其他的請求會直接返回,不繼續(xù)去請求依賴的服務)
官網對比線程池與信號量
?
什么時候用線程池 or 信號量?
默認使用線程池
如果不涉及遠程RPC調用(沒有網絡開銷),比如訪問內存緩存,則使用信號量來隔離,更為輕量,開銷更小。
The Netflix API processes 10+ billion Hystrix Command executions per day using thread isolation. Each API instance has 40+ thread-pools with 5–20 threads in each (most are set to 10).
Netflix API每天使用線程隔離處理10億次Hystrix Command執(zhí)行。 每個API實例都有40多個線程池,每個線程池中有5-20個線程(大多數設置為10個)
線程池核心配置:
服務降級、回退
降級就是當依賴的服務產生故障時,把產生故障的丟了,換一個輕量級的方案(比如返回一個固定值),是一種退而求其次的方法。比如微信剛上線紅包功能時,過年那天大家都在發(fā)紅包,很多人都會看到微信會彈出一個相同的頁面,這個就是服務降級的使用,當服務不可用時,返回一個靜態(tài)值(頁面)。
Hystrix 6種降級回退模式:
?
Sometimes if a back-end service fails, a stale version of data can be retrieved from a cache service such as memcached. 利用遠程緩存
通過遠程緩存的方式。在失敗的情況下再發(fā)起一次remote請求,不過這次請求的是一個緩存比如redis。由于是又發(fā)起一起遠程調用,所以會重新封裝一次Command,這個時候要注意,執(zhí)行fallback的線程一定要跟主線程區(qū)分開,也就是重新命名一個ThreadPoolKey。
?
這個有點類似我們日常開發(fā)中需要上線一個新功能,但為了防止新功能上線失敗可以回退到老的代碼,我們會做一個開關比如(使用zookeeper)做一個配置開關,可以動態(tài)切換到老代碼功能。那么Hystrix它是使用通過一個配置來在兩個command中進行切換。
?
回退的處理方式也有不適合的場景:
以上幾種情況如果失敗,則程序就要將錯誤返回給調用者。
熔斷器
熔斷器就像家里的保險絲,當電流過載了就會跳閘,不過Hystrix的熔斷機制相對復雜一些。
?
這兩個圖來自于兩個博客,都是同一個意思。
服務的健康狀況 = 請求失敗數 / 請求總數.
熔斷器開關由關閉到打開的狀態(tài)轉換是通過當前服務健康狀況和設定閾值比較決定的.
- 當熔斷器開關關閉時, 請求被允許通過熔斷器. 如果當前健康狀況高于設定閾值, 開關繼續(xù)保持關閉. 如果當前健康狀況低于設定閾值, 開關則切換為打開狀態(tài).
- 當熔斷器開關打開時, 請求被禁止通過.
- 當熔斷器開關處于打開狀態(tài), 經過一段時間后, 熔斷器會自動進入半開狀態(tài), 這時熔斷器只允許一個請求通過. 當該請求調用成功時, 熔斷器恢復到關閉狀態(tài). 若該請求失敗, 熔斷器繼續(xù)保持打開狀態(tài), 接下來的請求被禁止通過.
熔斷器的開關能保證服務調用者在調用異常服務時, 快速返回結果, 避免大量的同步等待. 并且熔斷器能在一段時間后繼續(xù)偵測請求執(zhí)行結果, 提供恢復服務調用的可能.
熔斷器核心配置:
Hystrix sequence diagram
-
Spring Cloud Hystrix的請求合并 代碼實例
-
由于請求合并器的延遲時間窗會帶來額外開銷
服務監(jiān)控
Hystrix還提供給我們一個監(jiān)控功能Hystrix-dashboard,可以直接使用其開源項目進行配置,就能實時的觀察我們的服務調用情況。
如果是集群,通過turbine進行監(jiān)視。
監(jiān)控如下:
Hystrix監(jiān)控面板
Hystrix監(jiān)控數據聚合
命令模式
Hystrix采用命令模式,將上述這些功能特性植入我們的業(yè)務代碼,值得學習。
參考文獻
- Netflix/Hystrix wiki
- 防雪崩利器:熔斷器 Hystrix 的原理與使用
- Hystrix技術解析
總結
以上是生活随笔為你收集整理的springcloud实践之断路器:Hystrix原理和解构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式锁中的王者方案:Redisson
- 下一篇: charles 如何抓取web界面的包