Sentinel vs Hystrix 限流對比,到底怎麼選?

来源:https://www.cnblogs.com/javastack/archive/2022/08/02/16544564.html
-Advertisement-
Play Games

Sentinel 是阿裡中間件團隊開源的,面向分散式服務架構的輕量級高可用流量控制組件,主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來幫助用戶保護服務的穩定性。 大家可能會問:Sentinel 和之前常用的熔斷降級庫 Netflix Hystrix 有什麼異同呢? 本文將從多個角 ...


Sentinel 是阿裡中間件團隊開源的,面向分散式服務架構的輕量級高可用流量控制組件,主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來幫助用戶保護服務的穩定性。

大家可能會問:Sentinel 和之前常用的熔斷降級庫 Netflix Hystrix 有什麼異同呢?

本文將從多個角度對 Sentinel 和 Hystrix 進行對比,幫助大家進行技術選型。

Overview

先來看一下 Hystrix 的官方介紹:

Hystrix is a library that helps you control the interactions between these distributed services by adding latency tolerance and fault tolerance logic. Hystrix does this by isolating points of access between the services, stopping cascading failures across them, and providing fallback options, all of which improve your system’s overall resiliency.

可以看到 Hystrix 的關註點在於以 隔離熔斷 為主的容錯機制,超時或被熔斷的調用將會快速失敗,並可以提供 fallback 機制。

而 Sentinel 的側重點在於:

  • 多樣化的流量控制
  • 熔斷降級
  • 系統負載保護
  • 實時監控和控制台

可以看到兩者解決的問題還是有比較大的不同的,下麵我們來分別對比一下。

共同特性

資源模型和執行模型上的對比

Hystrix 的資源模型設計上採用了命令模式,將對外部資源的調用和 fallback 邏輯封裝成一個命令對象(HystrixCommand / HystrixObservableCommand),其底層的執行是基於 RxJava 實現的。每個 Command 創建時都要指定 commandKey 和 groupKey(用於區分資源)以及對應的隔離策略(線程池隔離 or 信號量隔離)。線程池隔離模式下需要配置線程池對應的參數(線程池名稱、容量、排隊超時等),然後 Command 就會在指定的線程池按照指定的容錯策略執行;信號量隔離模式下需要配置最大併發數,執行 Command 時 Hystrix 就會限制其併發調用。

Sentinel 的設計則更為簡單。相比 Hystrix Command 強依賴隔離規則,Sentinel 的資源定義與規則配置的耦合度更低。Hystrix 的 Command 強依賴於隔離規則配置的原因是隔離規則會直接影響 Command 的執行。在執行的時候 Hystrix 會解析 Command 的隔離規則來創建 RxJava Scheduler 併在其上調度執行,若是線程池模式則 Scheduler 底層的線程池為配置的線程池,若是信號量模式則簡單包裝成當前線程執行的 Scheduler。而 Sentinel 並不指定執行模型,也不關註應用是如何執行的。Sentinel 的原則非常簡單:根據對應資源配置的規則來為資源執行相應的限流/降級/負載保護策略。在 Sentinel 中資源定義和規則配置是分離的。用戶先通過 Sentinel API 給對應的業務邏輯定義資源(埋點),然後可以在需要的時候配置規則。埋點方式有兩種:

  • try-catch 方式(通過 SphU.entry(...)),用戶在 catch 塊中執行異常處理 / fallback
  • if-else 方式(通過 SphO.entry(...)),當返回 false 時執行異常處理 / fallback

從 0.1.1 版本開始,Sentinel 還支持基於註解的資源定義方式,可以通過註解參數指定異常處理函數和 fallback 函數。

從 0.2.0 版本開始,Sentinel 引入非同步調用鏈路支持,可以方便地統計非同步調用資源的數據,維護非同步調用鏈路,同時具備了適配非同步框架/庫的能力。

Sentinel 提供多樣化的規則配置方式。除了直接通過 loadRules API 將規則註冊到記憶體態之外,用戶還可以註冊各種外部數據源來提供動態的規則。用戶可以根據系統當前的實時情況去動態地變更規則配置,數據源會將變更推送至 Sentinel 並即時生效。

隔離設計上的對比

隔離是 Hystrix 的核心功能之一。Hystrix 提供兩種隔離策略:線程池隔離(Bulkhead Pattern)和信號量隔離,其中最推薦也是最常用的是線程池隔離。Hystrix 的線程池隔離針對不同的資源分別創建不同的線程池,不同服務調用都發生在不同的線程池中,線上程池排隊、超時等阻塞情況時可以快速失敗,並可以提供 fallback 機制。線程池隔離的好處是隔離度比較高,可以針對某個資源的線程池去進行處理而不影響其它資源,但是代價就是線程上下文切換的 overhead 比較大,特別是對低延時的調用有比較大的影響。

但是,實際情況下,線程池隔離並沒有帶來非常多的好處。首先就是過多的線程池會非常影響性能。考慮這樣一個場景,在 Tomcat 之類的 Servlet 容器使用 Hystrix,本身 Tomcat 自身的線程數目就非常多了(可能到幾十或一百多),如果加上 Hystrix 為各個資源創建的線程池,總共線程數目會非常多(幾百個線程),這樣上下文切換會有非常大的損耗。另外,線程池模式比較徹底的隔離性使得 Hystrix 可以針對不同資源線程池的排隊、超時情況分別進行處理,但這其實是超時熔斷和流量控制要解決的問題,如果組件具備了超時熔斷和流量控制的能力,線程池隔離就顯得沒有那麼必要了。

Hystrix 的信號量隔離限制對某個資源調用的併發數。這樣的隔離非常輕量級,僅限制對某個資源調用的併發數,而不是顯式地去創建線程池,所以 overhead 比較小,但是效果不錯,也支持超時失敗。Sentinel 可以通過併發線程數模式的流量控制來提供信號量隔離的功能。並且結合基於響應時間的熔斷降級模式,可以在不穩定資源的平均響應時間比較高的時候自動降級,防止過多的慢調用占滿併發數,影響整個系統。

熔斷降級對比

Sentinel 和 Hystrix 的熔斷降級功能本質上都是基於熔斷器模式(Circuit Breaker Pattern)。Sentinel 與 Hystrix 都支持基於失敗比率(異常比率)的熔斷降級,在調用達到一定量級並且失敗比率達到設定的閾值時自動進行熔斷,此時所有對該資源的調用都會被 block,直到過了指定的時間視窗後才啟發性地恢復。上面提到過,Sentinel 還支持基於平均響應時間的熔斷降級,可以在服務響應時間持續飆高的時候自動熔斷,拒絕掉更多的請求,直到一段時間後才恢復。這樣可以防止調用非常慢造成級聯阻塞的情況。

實時指標統計實現對比

Hystrix 和 Sentinel 的實時指標數據統計實現都是基於滑動視窗的。Hystrix 1.5 之前的版本是通過環形數組實現的滑動視窗,通過鎖配合 CAS 的操作對每個桶的統計信息進行更新。Hystrix 1.5 開始對實時指標統計的實現進行了重構,將指標統計數據結構抽象成了響應式流(reactive stream)的形式,方便消費者去利用指標信息。同時底層改造成了基於 RxJava 的事件驅動模式,在服務調用成功/失敗/超時的時候發佈相應的事件,通過一系列的變換和聚合最終得到實時的指標統計數據流,可以被熔斷器或 Dashboard 消費。

Sentinel 目前抽象出了 Metric 指標統計介面,底層可以有不同的實現,目前預設的實現是基於 LeapArray 的高性能滑動視窗,後續根據需要可能會引入 reactive stream 等實現。

Sentinel 的特色

除了之前提到的兩者的共同特性之外,Sentinel 還提供以下的特色功能:

輕量級、高性能

Sentinel 作為一個功能完備的高可用流量管控組件,其核心 sentinel-core 沒有任何多餘依賴,打包後只有不到 200 KB,非常輕量級。開發者可以放心地引入 sentinel-core 而不需擔心依賴問題。同時,Sentinel 提供了多種擴展點,用戶可以很方便地根據需求去進行擴展,並且無縫地切合到 Sentinel 中。

引入 Sentinel 帶來的性能損耗非常小。只有在業務單機量級超過 25W QPS 的時候才會有一些顯著的影響(5% - 10% 左右),單機 QPS 不太大的時候損耗幾乎可以忽略不計。

流量控制

Sentinel 可以針對不同的調用關係,以不同的運行指標(如 QPS、併發調用數、系統負載等)為基準,對資源調用進行流量控制,將隨機的請求調整成合適的形狀。

Sentinel 支持多樣化的流量整形策略,在 QPS 過高的時候可以自動將流量調整成合適的形狀。常用的有:

  • 直接拒絕模式:即超出的請求直接拒絕。
  • 慢啟動預熱模式:當流量激增的時候,控制流量通過的速率,讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。

  • 勻速器模式:利用 Leaky Bucket 演算法實現的勻速模式,嚴格控制了請求通過的時間間隔,同時堆積的請求將會排隊,超過超時時長的請求直接被拒絕。

Sentinel 還支持 基於調用關係的限流,包括基於調用方限流、基於調用鏈入口限流、關聯流量限流等,依托於 Sentinel 強大的調用鏈路統計信息,可以提供精準的不同維度的限流。

Sentinel 0.2.0 開始支持 熱點參數限流,能夠實時的統計熱點參數並針對熱點參數的資源調用進行流量控制。

系統負載保護

Sentinel 對系統的維度提供保護,負載保護演算法借鑒了 TCP BBR 的思想。當系統負載較高的時候,如果仍持續讓請求進入,可能會導致系統崩潰,無法響應。在集群環境下,網路負載均衡會把本應這台機器承載的流量轉發到其它的機器上去。如果這個時候其它的機器也處在一個邊緣狀態的時候,這個增加的流量就會導致這台機器也崩潰,最後導致整個集群不可用。針對這個情況,Sentinel 提供了對應的保護機制,讓系統的入口流量和系統的負載達到一個平衡,保證系統在能力範圍之內處理最多的請求。

image-20211118104644863

實時監控與控制面板

Sentinel 提供 HTTP API 用於獲取實時的監控信息,如調用鏈路統計信息、簇點信息、規則信息等。如果用戶正在使用 Spring Boot/Spring Cloud 並使用了 Sentinel Spring Cloud Starter,還可以方便地通過其暴露的 Actuator Endpoint 來獲取運行時的一些信息,如動態規則等。未來 Sentinel 還會支持標準化的指標監控 API,可以方便地整合各種監控系統和可視化系統,如 Prometheus、Grafana 等。

Sentinel 控制台(Dashboard)提供了機器發現、配置規則、查看實時監控、查看調用鏈路信息等功能,使得用戶可以非常方便地去查看監控和進行配置。

生態

Sentinel 目前已經針對 Servlet、Dubbo、Spring Boot/Spring Cloud、gRPC 等進行了適配,用戶只需引入相應依賴併進行簡單配置即可非常方便地享受 Sentinel 的高可用流量防護能力。未來 Sentinel 還會對更多常用框架進行適配,並且會為 Service Mesh 提供集群流量防護的能力。

總結

最後用表格來進行對比總結:

Sentinel Hystrix
隔離策略 信號量隔離 線程池隔離/信號量隔離
熔斷降級策略 基於響應時間或失敗比率 基於失敗比率
實時指標實現 滑動視窗 滑動視窗(基於 RxJava)
規則配置 支持多種數據源 支持多種數據源
擴展性 多個擴展點 插件的形式
基於註解的支持 支持 支持
限流 基於 QPS,支持基於調用關係的限流 有限的支持
流量整形 支持慢啟動、勻速器模式 不支持
系統負載保護 支持 不支持
控制台 開箱即用,可配置規則、查看秒級監控、機器發現等 不完善
常見框架的適配 Servlet、Spring Cloud、Dubbo、gRPC 等 Servlet、Spring Cloud Netflix

參考:https://github.com/alibaba/Sentinel/wiki/

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 24 類型標註 24.1 Python中的數據類型 在Python中有很多數據類型,比較常見如下所示: |整型 | 浮點型|字元串 | 列表|元組|字典|集合|布爾| | | | | | | | | | |int| float|str|list|tuple|dict|set|bool| 因Pytho ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 大家好,我是“良工說技術”。 今天給大家帶來的是springboot中的@ConditionalOnClass註解的用法。上次的@ConditionalOnBean註解還記得嗎? 一、@ConditionalOnClass註解初始 看下@CodidtionalOnClass註解的定義, 需要註意的有 ...
  • 一、緩存機制的原理 一個系統在面向用戶使用的時候,當用戶的數量不斷增多,那麼請求次數也會不斷增多,當請求次數增多的時候,就會造成請求壓力,而我們當前的所有數據查詢都是從資料庫MySQL中直接查詢的,那麼就可能會產生如下問題 ==頻繁訪問資料庫,資料庫訪問壓力大,系統性能下降,用戶體驗差== 解決問題 ...
  • 今天我們來講解leetcode案例分析,如何動態規劃的解題套路,態規劃的核心思想,以前經常會遇到動態規劃類型題目。 ...
  • SpringBoot 2.7.2 學習系列,本節內容快速體驗Spring Boot,帶大家瞭解它的基本使用、運行和打包。 Spring Boot 基於 Spring 框架,底層離不開 IoC、AoP 等核心思想。Spring 4.0 提供了基於 Java Config 的開發方式,Spring Bo ...
  • 一、問題復現 在實際的軟體系統開發過程中,隨著使用的用戶群體越來越多,表數據也會隨著時間的推移,單表的數據量會越來越大。 以訂單表為例,假如每天的訂單量在 4 萬左右,那麼一個月的訂單量就是 120 多萬,一年就是 1400 多萬,隨著年數的增加和單日下單量的增加,訂單表的數據量會越來越龐大,訂單數 ...
  • 1. 登錄表單配置 1.1 快速入門 理解了入門案例之後,接下來我們再來看一下登錄表單的詳細配置,首先創建一個新的Spring Boot項目,引入Web和Spring Security依賴,代碼如下: <dependency> <groupId>org.springframework.boot</g ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...