背景
分佈式系統環境下,服務間相似依賴很是常見,一個業務調用一般依賴多個基礎服務。以下圖,對於同步調用,當庫存服務不可用時,商品服務請求線程被阻塞,當有大批量請求調用庫存服務時,最終可能致使整個商品服務資源耗盡,沒法繼續對外提供服務。而且這種不可用可能沿請求調用鏈向上傳遞,這種現象被稱爲雪崩效應。緩存
雪崩效應應對策略
針對形成雪崩效應的不一樣場景,可使用不一樣的應對策略,沒有一種通用全部場景的策略,參考以下:網絡
- 硬件故障:多機房容災、異地多活等。
- 流量激增:服務自動擴容、流量控制(限流、關閉重試)等。
- 緩存穿透:緩存預加載、緩存異步加載等。
- 程序BUG:修改程序bug、及時釋放資源等。
- 同步等待:資源隔離、MQ解耦、不可用服務調用快速失敗等。資源隔離一般指不一樣服務調用採用不一樣的線程池;不可用服務調用快速失敗通常經過熔斷器模式結合超時機制實現。
綜上所述,若是一個應用不能對來自依賴的故障進行隔離,那該應用自己就處在被拖垮的風險中。 所以,爲了構建穩定、可靠的分佈式系統,咱們的服務應當具備自我保護能力,當依賴服務不可用時,當前服務啓動自我保護功能,從而避免發生雪崩效應。本文將重點介紹使用Hystrix解決同步等待的雪崩問題。框架
初探Hystrix
Hystrix [hɪst'rɪks],中文含義是豪豬,因其背上長滿棘刺,從而擁有了自我保護的能力。本文所說的Hystrix是Netflix開源的一款容錯框架,一樣具備自我保護能力。爲了實現容錯和自我保護,下面咱們看看Hystrix如何設計和實現的。異步
Hystrix設計目標:分佈式
- 對來自依賴的延遲和故障進行防禦和控制——這些依賴一般都是經過網絡訪問的
- 阻止故障的連鎖反應
- 快速失敗並迅速恢復
- 回退並優雅降級
- 提供近實時的監控與告警
Hystrix遵循的設計原則:線程
- 防止任何單獨的依賴耗盡資源(線程)
- 過載當即切斷並快速失敗,防止排隊
- 儘量提供回退以保護用戶免受故障
- 使用隔離技術(例如隔板,泳道和斷路器模式)來限制任何一個依賴的影響
- 經過近實時的指標,監控和告警,確保故障被及時發現
- 經過動態修改配置屬性,確保故障及時恢復
- 防止整個依賴客戶端執行失敗,而不單單是網絡通訊
Hystrix如何實現這些設計目標?設計
- 使用命令模式將全部對外部服務(或依賴關係)的調用包裝在HystrixCommand或HystrixObservableCommand對象中,並將該對象放在單獨的線程中執行;
- 每一個依賴都維護着一個線程池(或信號量),線程池被耗盡則拒絕請求(而不是讓請求排隊)。
- 記錄請求成功,失敗,超時和線程拒絕。
- 服務錯誤百分比超過了閾值,熔斷器開關自動打開,一段時間內中止對該服務的全部請求。
- 請求失敗,被拒絕,超時或熔斷時執行降級邏輯。
- 近實時地監控指標和配置的修改。