服務雪崩效應
基礎服務的故障導致級聯故障,進而造成了整個分布式系統的不可用,這種現象被稱為服務雪崩效應。服務雪崩效應描述的是一種因服務提供者的不可用導致服務消費者的不可用,並將不可用逐漸放大的過程。
服務雪崩效應形成的原因
- 服務提供者不可用
- 硬件故障
- 程序Bug
- 緩存擊穿
- 用戶大量請求
- 重試加大流量
- 用戶重試
- 代碼邏輯重試
- 服務調用者不可用
- 同步等待造成的資源耗盡
服務雪崩的應對策略
- 流量控制
- 網關限流
- 用戶交互限流
- 關閉重試
- 改進緩存模式
- 緩存預加載
- 同步改為異步刷新
- 服務自動擴容
- AWS的auto scaling
- 服務調用者降級服務
- 資源隔離
- 對依賴服務進行分類
- 不可用服務的調用快速失敗
打鐵還需自身硬,本篇文章不展開論述各種應對策略,主要探討微服務自身如何來保護自己,避免奔潰?即微服務如何進行容錯設計?
容量設計在生活中經常見到,每家每戶都有保險絲,用電超負荷了,就會跳閘。微服務的容錯組件Hystrix就吸收了這些思想。
Hystrix
Hystrix [hɪst'rɪks]的中文含義是豪豬科動物,如下圖所示, 因其背上長滿了刺,而擁有自我保護能力.
Netflix的 Hystrix 是一個幫助解決分布式系統交互時超時處理和容錯的類庫, 它同樣擁有保護系統的能力.
Hystrix如何保護我們的應用?
How Does Hystrix Accomplish Its Goals?
- Wrapping all calls to external systems (or “dependencies”) in a HystrixCommand or HystrixObservableCommand object which typically executes within a separate thread (this is an example of the command pattern).(通過HystrixCommand封裝外部系統的所有調用,它會在獨立的線程中執行)即命令模式。
- Timing-out calls that take longer than thresholds you define. There is a default, but for most dependencies you custom-set these timeouts by means of “properties” so that they are slightly higher than the measured 99.5th percentile performance for each dependency.(簡單說:修改超時時間的閾值,提高依賴的性能)
- Maintaining a small thread-pool (or semaphore) for each dependency; if it becomes full, requests destined for that dependency will be immediately rejected instead of queued up.(每個依賴維護一個小的線程池或者信號量,如果滿了,請求調用依賴會被快速聚集而不是排隊等待。)即資源隔離
- Measuring successes, failures (exceptions thrown by client), timeouts, and thread rejections.(測量成功率,失敗率、超時次數、線程拒絕率)即服務監控的指標
- Tripping a circuit-breaker to stop all requests to a particular service for a period of time, either manually or automatically if the error percentage for the service passes a threshold.(當服務的錯誤率超過閾值時,通過手動或者自動的方式,對一定時間內特定的服務,采用鏈路中斷器拒絕所有請求,)即熔斷器、熔斷機制
- Performing fallback logic when a request fails, is rejected, times-out, or short-circuits.(在請求失敗、拒絕、超時、短路時執行回退邏輯)即請求回退
- Monitoring metrics and configuration changes in near real-time.(近實時監控指標和修改配置。)
下面主要展開講述資源隔離、服務降級、服務熔斷、請求合並以及服務監控等功能特性。
資源隔離
資源隔離--設計思想來源
貨船為了進行防止漏水和火災等風險的擴散,會將貨倉分隔為多個隔離區域,這種資源隔離減少風險的方式被稱為:Bulkheads(艙壁隔離模式).
官網關於資源隔離的舉例如下:
兩種資源隔離模式
(1)線程池隔離模式:使用一個線程池來存儲當前的請求,線程池對請求作處理,設置任務返回處理超時時間,堆積的請求堆積入線程池隊列。這種方式需要為每個依賴的服務申請線程池,有一定的資源消耗,好處是可以應對突發流量(流量洪峰來臨時,處理不完可將數據存儲到線程池隊里慢慢處理)
(2)信號量隔離模式:使用一個原子計數器(或信號量)來記錄當前有多少個線程在運行,請求來先判斷計數器的數值,若超過設置的最大線程個數則丟棄改類型的新請求,若不超過則執行計數操作請求來計數器+1,請求返回計數器-1。這種方式是嚴格的控制線程且立即返回模式,無法應對突發流量(流量洪峰來臨時,處理的線程超過數量,其他的請求會直接返回,不繼續去請求依賴的服務)
官網對比線程池與信號量
什么時候用線程池 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執行。 每個API實例都有40多個線程池,每個線程池中有5-20個線程(大多數設置為10個)
@HystrixCommand(fallbackMethod = "stubMyService",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
}
)
線程池核心配置:
服務降級、回退
降級就是當依賴的服務產生故障時,把產生故障的丟了,換一個輕量級的方案(比如返回一個固定值),是一種退而求其次的方法。比如微信剛上線紅包功能時,過年那天大家都在發紅包,很多人都會看到微信會彈出一個相同的頁面,這個就是服務降級的使用,當服務不可用時,返回一個靜態值(頁面)。
Hystrix 6種降級回退模式:
- Fail Fast 快速失敗
- Fail Silent 無聲失敗
- Fallback: Static 返回默認值
- Fallback: Stubbed 自己組裝一個值返回
- Cache via Network
Sometimes if a back-end service fails, a stale version of data can be retrieved from a cache service such as memcached. 利用遠程緩存
通過遠程緩存的方式。在失敗的情況下再發起一次remote請求,不過這次請求的是一個緩存比如redis。由於是又發起一起遠程調用,所以會重新封裝一次Command,這個時候要注意,執行fallback的線程一定要跟主線程區分開,也就是重新命名一個ThreadPoolKey。
- Primary + Secondary with Fallback 主次方式回退(主要和次要)
這個有點類似我們日常開發中需要上線一個新功能,但為了防止新功能上線失敗可以回退到老的代碼,我們會做一個開關比如(使用zookeeper)做一個配置開關,可以動態切換到老代碼功能。那么Hystrix它是使用通過一個配置來在兩個command中進行切換。
回退的處理方式也有不適合的場景:
以上幾種情況如果失敗,則程序就要將錯誤返回給調用者。
熔斷器
熔斷器就像家里的保險絲,當電流過載了就會跳閘,不過Hystrix的熔斷機制相對復雜一些。
這兩個圖來自於兩個博客,都是同一個意思。
服務的健康狀況 = 請求失敗數 / 請求總數.
熔斷器開關由關閉到打開的狀態轉換是通過當前服務健康狀況和設定閾值比較決定的.
- 當熔斷器開關關閉時, 請求被允許通過熔斷器. 如果當前健康狀況高於設定閾值, 開關繼續保持關閉. 如果當前健康狀況低於設定閾值, 開關則切換為打開狀態.
- 當熔斷器開關打開時, 請求被禁止通過.
- 當熔斷器開關處於打開狀態, 經過一段時間后, 熔斷器會自動進入半開狀態, 這時熔斷器只允許一個請求通過. 當該請求調用成功時, 熔斷器恢復到關閉狀態. 若該請求失敗, 熔斷器繼續保持打開狀態, 接下來的請求被禁止通過.
熔斷器的開關能保證服務調用者在調用異常服務時, 快速返回結果, 避免大量的同步等待. 並且熔斷器能在一段時間后繼續偵測請求執行結果, 提供恢復服務調用的可能.
熔斷器工作流程圖
熔斷器核心配置:
Hystrix工作流程圖
上圖是官網原圖,下圖是中文版:
Hystrix sequence diagram
請求合並
-
由於請求合並器的延遲時間窗會帶來額外開銷
服務監控
Hystrix還提供給我們一個監控功能Hystrix-dashboard,可以直接使用其開源項目進行配置,就能實時的觀察我們的服務調用情況。
如果是集群,通過turbine進行監視。
監控如下:
命令模式
Hystrix采用命令模式,將上述這些功能特性植入我們的業務代碼,值得學習。
參考文獻
tips:本文屬於自己學習和實踐過程的記錄,很多圖和文字都粘貼自網上文章,沒有注明引用請包涵!如有任何問題請留言或郵件通知,我會及時回復。