使用Netflix Hystrix編寫彈性可容錯的應用程序

彈性指的是在複雜網絡環境下,面對各種故障和挑戰,仍能提供和維持一個可以接受的服務水平,並正常運作。
-來自Wikipedia

自從長期服務和最近的微服務被大家熟知和使用,很多應用程序開發人員已經將整體式的API,轉換成簡單的、功能單一的微服務。然而,這樣的轉換,導致爲了保證一致的響應時間和彈性,依賴關係變得不可用時,造成額外的損耗。例如,一個單體式的web應用程序,執行一次重試,在一定程度上是彈性的,因爲它可以在某些依賴關係(如數據庫或其他服務)不可用時恢復。這種恢復能力沒有任何附加的網絡損耗或代碼複雜度。

對於一個需要編排依賴的服務,每次調用都是昂貴的,失敗會導致降低用戶體驗,特別是當試圖從失敗中恢復時。將對後端服務造成更大的壓力

斷路器模式

考慮一個典型的使用案例:一個電子商務網站,在黑色星期五時服務器超載,由於壓力過大,供應商提供的付款系統脫機了幾秒鐘。由於高併發請求,用戶開始看到結帳時長時間的無響應。這些條件也導致了所有的應用程序服務器都被阻塞,而這些阻塞線程正在等待接收來自供應商的響應。經過漫長的等待時間,最終的結果是失敗。

這些事件導致了無效的購物車,用戶試圖更新或重新下訂單,進一步擴大了應用服務器的負載,應用服務器上已經堆積了大量等待線程,導致網絡擁塞。

斷路器是一種簡單的設計結構,它時常保持警惕,對故障進行監控。在上述情況下,當斷路器發現在調用供應商接口時,發生了長等待時間,那麼使用fail fast策略,向用戶返回一個錯誤響應,而不是使線程長時間等待。因此,斷路器可以防止用戶等待時間過長。

斷路器背後的基本思想是很簡單的。在斷路器對象中,包含一個受保護的函數調用,並由該斷路器對象進行故障監測。一旦故障出現,並達到一定的閾值,斷路器跳閘,斷路器中剩下的調用都將返回一個錯誤,而不是將所有步驟繼續執行下去。通常,如果斷路器跳閘,你還需要進一步的監控和告警。
– Martin Fowler

恢復時間對底層資源至關重要,有了一個快速失敗的斷路器,保護了超載的系統,使下游服務能快速恢復。

斷路器是一直活躍在系統中,時刻監視系統的依賴調用。爲了防止高故障率,斷路器在很短的時間內便能停止失敗調用的擴散,而不是僅僅返回一個標準的錯誤。

eBay與斷路器

在很早之前,我們使用一個簡單的設置方案名爲AUTO_MARK_DOWN,用於防止漫長的依賴調用等待問題。通過將失敗的調用短路,直到他們通過MARK_UP標記恢復。自動檢查系統定期檢查各種機器每一個依賴的AUTO_MARK_DOWN狀態,並執行MARK_UP。

然而,自動檢查系統和MARK_UP設施並不是內嵌到應用系統,而是位於外部。由於沒有關於請求量和故障率的持續不斷的反饋,會出現一個未經驗證就被標記爲MARK_UP的系統依賴異常。依託這個設置也導致了誤報,由於自動檢查系統是客戶端之外,無法評估失敗的連續性。

另一個該設計的主要缺陷是,沒辦法對所有應用程序的依賴做全面的,實時的監控。這個舊系統是緩慢和不穩定的,沒有持續的遙測,盲目標記所有系統的auto_mark_down,假定應用程序的依賴將進一步產生故障。其結果是不可預測的,難以正確評估。

斷路器的恢復

斷路器在適當的時候需要注意跳閘了的依賴服務。一個更復雜的系統需要持續保持警惕,以確定依賴調用是否可用,如果沒問題,則讓依賴調用繼續下去。

這種行爲可以用2種方式實現:
1. 允許所有調用執行,在一個正常的時間間隔內執行並檢查錯誤。
2. 允許一個單一的調用執行,更頻繁的速度來衡量可用性。

AUTO_MARK_DOWN是第一種方式,其中,電路在沒有任何恢復的情況下被關閉,並依靠錯誤識別問題。

第二種方式是一個更復雜的機制,因爲它不允許多個調用同時執行,因爲調用可能需要很長的時間來執行但是仍然失敗。然而,只允許一個單一的調用執行,需確保更快的執行,從而實現了系統電路的恢復和更快的收斂。

理想的斷路器

一個和諧的系統,應有一個理想的斷路器,實時監測,並能快速恢復故障,使應用程序達到真正的彈性可容錯。

斷路器 + 實時監測 + 恢復 = 彈性可容錯
– 匿名

使用上面的電子商務網站爲例,在一個彈性系統中,斷路器持續對系統進行故障評估,在付款處理器發生故障時,發現由於供應商而造成的長時間等待。在這種情況下,它打破了電路,並快速失敗。其結果是,用戶被告知系統故障,供應商有足夠的時間來恢復。

同時,斷路器也不斷地發送一個請求,以確認供應商系統是否恢復。如果是這樣的話,斷路器將閉合電路,允許其餘的調用正常執行,從而有效地消除網絡擁塞和長時間等待的問題。

Netflix Hystrix

Hystrix是一個能夠爲延遲和故障提供更強大的容錯能力的庫,通過隔離訪問遠程系統、服務和第三方庫的節點,阻止級聯故障,從而使複雜的分佈式系統更具彈性。
– Netflix

自從2012成立以來,Hystrix成爲許多試圖爲系統提高處理能力和解決故障的解決方法。它有一個相當成熟的接口和一個高度可調的配置系統,使應用程序開發人員能夠提供最佳的服務依賴調用。

Hystrix斷路器的狀態

下面的狀態圖,描述了中斷路器生命週期中不同狀態下彈性可容錯系統的運作情況。

Circuit Breaker State Diagram

正常運行(Closed)

當一個系統運行平穩,成功狀態計數器用於測量彈性系統的穩定性,而故障表用於跟蹤任何故障。該設計確保當達到故障的閾值時,斷路器斷開電路,以防止進一步的資源請求。

失敗狀態(Open)

在這個時刻,每一個依賴調用是短路的,並拋出HystrixRuntimeException異常,伴隨SHORTCIRCUIT失敗類型,給出異常明確的原因。一旦等待時間過後,Hystrix斷路器移到半開放狀態。

半開放狀態

在這種狀態下,由Hystrix負責發送第一個請求,檢查系統的可用性,讓其他的請求快速失敗,直到得到依賴的響應。如果調用是成功的,斷路器被重置爲Closed狀態;如果發生故障,系統返回Open狀態,並且整個過程繼續循環。

如何使用Hystrix

Hystrix Github上有一個全面的文檔介紹如何使用Hystrix。這很簡單,只要使用Hystrix庫創建類並調用服務。

public class CommandHelloWorld extends HystrixCommand<String> {

        private final String name;

        public CommandHelloWorld(String name) {
            super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
            this.name = name;
        }

        @Override
        protected String run() {
            // a real example would do work like a network call here
            return "Hello " + name + "!";
        }
    }

Reference: https://github.com/Netflix/Hystrix/wiki/Getting-Started

在內部,這個類利用rxjava庫異步執行服務依賴的調用。此設計使用應用程序的線程,最大化程序性能,並智能管理服務資源調用。對於使用延遲調用的方式執行並行處理管理依賴關係的應用程序開發人員,Hystrix也提供Future

eBay如何使用Hystrix

在eBay,許多應用已經開始使用Hystrix,要麼作爲一個獨立的庫或使用我們的平臺包裝。我們平臺包裝的版本,通過JMX beans方式暴露Hystrix配置,方便集中管理。對於關鍵系統,我們包裝的版本還注入自定義Hystric插件實現捕獲實時被髮布的metrics,並feed到我們的監控系統。

Hystric的dashboard作爲核心服務器監控系統的一部分,使團隊能夠查看他們的應用程序不同時期的依賴情況。

Hystrix提供的execution hook是系統整合的一個關鍵組成部分,因爲它有助於實時監測/預警,尤其是錯誤和回退失敗的各種故障,從而幫助我們更迅速的調查和解決問題,幾乎沒有造成任何對用戶的影響。

eBay使用實例: Secure Token service

eBay有一系列的內部和外部的API服務。所有這些服務都是通過令牌認證,安全令牌服務作爲令牌的發行人和驗證。所有的令牌服務現在都升級並使用基於Hytrix斷路器,它使安全令牌服務高可用。當有一個服務在繁忙時,該服務的斷路器打開,不會對令牌服務造成壓力,同時允許其他服務功能正常。

Secure Token Service protected using Hystrix

斷路器是Hystrix庫默認提供的一個功能。斷路器的功能可以概括如下:
1. 斷路器對所有調用狀態進行驗證。
2. 電路的Closed狀態允許請求通過。
3. 一個Open狀態失敗所有請求。
4. 一個Half-Open狀態(當sleep等待時間完成),允許一個請求通過,並在成功或失敗時,轉換成Closed的或Open的狀態。

enter image description here

總結

Hystrix不僅僅是一個斷路器,也是一個具有豐富監控功能的完整的庫,可以很容易地植入到現有系統。我們已經開始爲未來的使用情況探索,使用該庫的請求崩潰請求緩存的功能。當然,還有一些其他的Java實現,如Akka和Spring斷路器,然而,根據我們彈性環境中,關鍵應用運行情況,Hystrix已經被證明是一個成熟的庫,提供任何時間段內的高可用性。

References

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章