Netflix開源的限流組件 Hystrix在其Github主頁宣布,不再開放新功能,推薦開發(fā)者使用其他仍然活躍的開源項目。
開發(fā)者可以繼續(xù)使用Hystrix的最新版本1.5.18,或者選擇Resilience4j和Sentinel。
(1)Resilience4j:是一個受 Netflix Hystrix 啟發(fā)的輕量級容錯庫,但是是為 Java 8和函數(shù)式編程設(shè)計的。輕量級,因為這個庫只使用了 Vavr (以前叫做 Javaslang) ,沒有任何其他的外部庫依賴。相比之下,Netflix Hystrix 對 Archaius 有一個編譯依賴,Archaius 有更多的外部庫依賴,比如 Guava 和 Apache Commons configurations。
(2)Sentinel:是面向分布式服務(wù)架構(gòu)的輕量級高可用流量控制組件。Sentinel 主要以流量為切入點,從流量控制、熔斷降級、系統(tǒng)負載保護等多個維度來幫助用戶提升服務(wù)的穩(wěn)定性。
1 功能對比

(1)Hystrix 的側(cè)重點在于:
- 以 隔離 和 熔斷 為主的容錯機制,超時或被熔斷的調(diào)用將會快速失敗,并可以提供 fallback 機制。
(2)Sentinel 的側(cè)重點在于:
- 多樣化的流量控制
- 熔斷降級
- 系統(tǒng)負載保護
- 實時監(jiān)控和控制臺
2 資源模型和執(zhí)行模型對比
(1)Hystrix 的資源模型設(shè)計上采用了命令模式,將對外部資源的調(diào)用和 fallback 邏輯封裝成一個命令對象(HystrixCommand / HystrixObservableCommand),其底層的執(zhí)行是基于 RxJava 實現(xiàn)的。每個 Command 創(chuàng)建時都要指定 commandKey 和 groupKey(用于區(qū)分資源)以及對應(yīng)的隔離策略(線程池隔離 or 信號量隔離)。線程池隔離模式下需要配置線程池對應(yīng)的參數(shù)(線程池名稱、容量、排隊超時等),然后 Command 就會在指定的線程池按照指定的容錯策略執(zhí)行;信號量隔離模式下需要配置最大并發(fā)數(shù),執(zhí)行 Command 時 Hystrix 就會限制其并發(fā)調(diào)用。
(2)區(qū)別于 Hystrix Command 強依賴隔離規(guī)則,Sentinel 的資源定義與規(guī)則配置的耦合度更低。Hystrix 的 Command 強依賴于隔離規(guī)則配置的原因是隔離規(guī)則會直接影響 Command 的執(zhí)行。在執(zhí)行的時候 Hystrix 會解析 Command 的隔離規(guī)則來創(chuàng)建 RxJava Scheduler 并在其上調(diào)度執(zhí)行,若是線程池模式則 Scheduler 底層的線程池為配置的線程池,若是信號量模式則簡單包裝成當(dāng)前線程執(zhí)行的 Scheduler。而 Sentinel 并不指定執(zhí)行模型,也不關(guān)注應(yīng)用是如何執(zhí)行的。Sentinel 的原則非常簡單:根據(jù)對應(yīng)資源配置的規(guī)則來為資源執(zhí)行相應(yīng)的限流/降級/負載保護策略。在 Sentinel 中資源定義和規(guī)則配置是分離的。用戶可以通過 Sentinel API 給對應(yīng)的業(yè)務(wù)邏輯定義資源(埋點),然后可以在需要的時候配置規(guī)則;或者直接使用@SentinelResource 注解,指定blockHandler或fallbackHandler進行熔斷降級。
3 隔離對比
(1)Hystrix 提供兩種隔離策略:線程池隔離和信號量隔離,其中最常用的是線程池隔離。Hystrix 的線程池隔離針對不同的資源分別創(chuàng)建不同的線程池,不同服務(wù)調(diào)用都發(fā)生在不同的線程池中,在線程池排隊、超時等阻塞情況時可以快速失敗,并可以提供 fallback 機制。線程池隔離的好處是隔離度比較高,可以針對某個資源的線程池去進行處理而不影響其它資源,但是代價就是線程上下文切換的 overhead 比較大,特別是對低延時的調(diào)用有比較大的影響。
但實際線程池隔離并沒有帶來非常多的好處。首先就是過多的線程池會非常影響性能。上下文切換會有非常大的損耗。另外,線程池模式比較徹底的隔離性使得 Hystrix 可以針對不同資源線程池的排隊、超時情況分別進行處理,但這其實是超時熔斷和流量控制要解決的問題,如果組件具備了超時熔斷和流量控制的能力,線程池隔離就顯得沒有那么必要了。
(2)Sentinel 通過并發(fā)線程數(shù)模式的流量控制來提供信號量隔離的功能。這樣的隔離非常輕量級,僅限制對某個資源調(diào)用的并發(fā)數(shù),而不是顯式地去創(chuàng)建線程池,所以 overhead 比較小,但是效果不錯。并且結(jié)合基于響應(yīng)時間的熔斷降級模式,可以在不穩(wěn)定資源的平均響應(yīng)時間比較高的時候自動降級,防止過多的慢調(diào)用占滿并發(fā)數(shù),影響整個系統(tǒng)。而 Hystrix 的信號量隔離比較簡單,無法對慢調(diào)用自動進行降級,只能等待客戶端自己超時,因此仍然可能會出現(xiàn)級聯(lián)阻塞的情況。
4 熔斷降級對比
Sentinel 和 Hystrix 的熔斷降級功能本質(zhì)上都是基于熔斷器模式。Sentinel 與 Hystrix 都支持基于失敗比率(異常比率)的熔斷降級,在調(diào)用達到一定量級并且失敗比率達到設(shè)定的閾值時自動進行熔斷,此時所有對該資源的調(diào)用都會被 block,直到過了指定的時間窗口后才啟發(fā)性地恢復(fù)。上面提到過,Sentinel 還支持基于平均響應(yīng)時間的熔斷降級,可以在服務(wù)響應(yīng)時間持續(xù)飆高的時候自動熔斷,拒絕掉更多的請求,直到一段時間后才恢復(fù)。這樣可以防止調(diào)用非常慢造成級聯(lián)阻塞的情況。
5 實時統(tǒng)計對比
Hystrix 和 Sentinel 的實時指標(biāo)數(shù)據(jù)統(tǒng)計實現(xiàn)都是基于滑動窗口的。
(1)Hystrix 1.5 之前的版本是通過環(huán)形數(shù)組實現(xiàn)的滑動窗口,通過鎖配合 CAS 的操作對每個桶的統(tǒng)計信息進行更新。Hystrix 1.5 開始對實時指標(biāo)統(tǒng)計的實現(xiàn)進行了重構(gòu),將指標(biāo)統(tǒng)計數(shù)據(jù)結(jié)構(gòu)抽象成了響應(yīng)式流的形式,方便消費者去利用指標(biāo)信息。同時底層改造成了基于 RxJava 的事件驅(qū)動模式,在服務(wù)調(diào)用成功/失敗/超時的時候發(fā)布相應(yīng)的事件,通過一系列的變換和聚合最終得到實時的指標(biāo)統(tǒng)計數(shù)據(jù)流,可以被熔斷器或 Dashboard 消費。
(2)Sentinel 目前抽象出了 Metric 指標(biāo)統(tǒng)計接口,底層可以有不同的實現(xiàn),目前默認的實現(xiàn)是基于 LeapArray 的滑動窗口,Sentinel 1.5.0版本引入 reactive 支持。
6 Sentinel特色
6.1 輕量級、高性能
Sentinel 作為一個功能完備的高可用流量管控組件,其核心 sentinel-core 沒有任何多余依賴,打包后只有不到 200 KB,非常輕量級。開發(fā)者可以放心地引入 sentinel-core 而不需擔(dān)心依賴問題。同時,Sentinel 提供了多種擴展點,用戶可以很方便地根據(jù)需求去進行擴展,并且無縫地切合到 Sentinel 中。
引入 Sentinel 帶來的性能損耗非常小。只有在業(yè)務(wù)單機量級超過 25W QPS 的時候才會有一些顯著的影響(5% - 10% 左右),單機 QPS 不太大的時候損耗幾乎可以忽略不計。
6.2 流量控制
Sentinel 可以針對不同的調(diào)用關(guān)系,以不同的運行指標(biāo)(如 QPS、并發(fā)調(diào)用數(shù)、系統(tǒng)負載等)為基準,對資源調(diào)用進行流量控制,將隨機的請求調(diào)整成合適的形狀。
Sentinel 支持多樣化的流量整形策略,在 QPS 過高的時候可以自動將流量調(diào)整成合適的模式。常用的有:
- 直接拒絕模式:即超出的請求直接拒絕。
- 慢啟動預(yù)熱模式:當(dāng)流量激增的時候,控制流量通過的速率,讓通過的流量緩慢增加,在一定時間內(nèi)逐漸增加到閾值上限,給冷系統(tǒng)一個預(yù)熱的時間,避免冷系統(tǒng)被壓垮。
- 勻速器模式:利用 Leaky Bucket 算法實現(xiàn)的勻速模式,嚴格控制了請求通過的時間間隔,同時堆積的請求將會排隊,超過超時時長的請求直接被拒絕。
6.3 系統(tǒng)負載保護
Sentinel 對系統(tǒng)的維度提供保護,負載保護算法借鑒了 TCP BBR 的思想。當(dāng)系統(tǒng)負載較高的時候,如果仍持續(xù)讓請求進入,可能會導(dǎo)致系統(tǒng)崩潰,無法響應(yīng)。在集群環(huán)境下,網(wǎng)絡(luò)負載均衡會把本應(yīng)這臺機器承載的流量轉(zhuǎn)發(fā)到其它的機器上去。如果這個時候其它的機器也處在一個邊緣狀態(tài)的時候,這個增加的流量就會導(dǎo)致這臺機器也崩潰,最后導(dǎo)致整個集群不可用。針對這個情況,Sentinel 提供了對應(yīng)的保護機制,讓系統(tǒng)的入口流量和系統(tǒng)的負載達到一個平衡,保證系統(tǒng)在能力范圍之內(nèi)處理最多的請求。
參考:
https://yq.aliyun.com/articles/623424
https://www.codercto.com/a/69027.html