這是圍繞 Sentinel 的使用場景株扛、技術(shù)對比和實現(xiàn)和二、開發(fā)者實踐等維度推出的系列文章的第三篇贫母。
第一篇回顧:
Dubbo 的流量防衛(wèi)兵 | Sentinel如何通過限流實現(xiàn)服務(wù)的高可用性 - 傳送門
第二篇回顧:
RocketMQ 的保險絲| Sentinel 如何通過勻速請求和冷啟動來保障服務(wù)的穩(wěn)定性 - 傳送門
Sentinel 是阿里中間件團隊研發(fā)的面向分布式服務(wù)架構(gòu)的輕量級高可用流量控制組件幅虑,于今年7月正式開源丰滑。Sentinel 主要以流量為切入點,從流量控制倒庵、熔斷降級褒墨、系統(tǒng)負載保護等多個維度來幫助用戶提升服務(wù)的穩(wěn)定性。大家可能會問:Sentinel 和之前經(jīng)常用到的熔斷降級庫 Netflix Hystrix 有什么異同呢擎宝?本文將從資源模型和執(zhí)行模型郁妈、隔離設(shè)計、熔斷降級认臊、實時指標統(tǒng)計設(shè)計等角度將 Sentinel 和 Hystrix 進行對比圃庭,希望在面臨技術(shù)選型的時候,對各位開發(fā)者能有所幫助失晴。
Sentinel 項目地址:
https://github.com/alibaba/Sentinel
一剧腻、總體說明
先來看一下 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 的關(guān)注點在于以隔離和熔斷為主的容錯機制,超時或被熔斷的調(diào)用將會快速失敗涂屁,并可以提供 fallback 機制书在。
而 Sentinel 的側(cè)重點在于:
多樣化的流量控制
熔斷降級
系統(tǒng)負載保護
實時監(jiān)控和控制臺
可以看到兩者解決的問題還是有比較大的不同的,下面我們來具體對比一下拆又。
二儒旬、共同特性
1栏账、資源模型和執(zhí)行模型上的對比
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)用。
Sentinel 的設(shè)計則更為簡單迄埃。相比 Hystrix Command 強依賴隔離規(guī)則疗韵,Sentinel 的資源定義與規(guī)則配置的耦合度更低。Hystrix 的 Command 強依賴于隔離規(guī)則配置的原因是隔離規(guī)則會直接影響 Command 的執(zhí)行侄非。在執(zhí)行的時候 Hystrix 會解析 Command 的隔離規(guī)則來創(chuàng)建 RxJava Scheduler 并在其上調(diào)度執(zhí)行蕉汪,若是線程池模式則 Scheduler 底層的線程池為配置的線程池,若是信號量模式則簡單包裝成當前線程執(zhí)行的 Scheduler逞怨。
而Sentinel則不一樣肤无,開發(fā)的時候只需要考慮這個方法/代碼是否需要保護,置于用什么來保護骇钦,可以任何時候動態(tài)實時的區(qū)修改。
從 0.1.1 版本開始竞漾,Sentinel 還支持基于注解的資源定義方式眯搭,可以通過注解參數(shù)指定異常處理函數(shù)和 fallback 函數(shù)。Sentinel 提供多樣化的規(guī)則配置方式业岁。除了直接通過 loadRules
API 將規(guī)則注冊到內(nèi)存態(tài)之外鳞仙,用戶還可以注冊各種外部數(shù)據(jù)源來提供動態(tài)的規(guī)則。用戶可以根據(jù)系統(tǒng)當前的實時情況去動態(tài)地變更規(guī)則配置笔时,數(shù)據(jù)源會將變更推送至 Sentinel 并即時生效棍好。
2、隔離設(shè)計上的對比
隔離是 Hystrix 的核心功能之一允耿。Hystrix 提供兩種隔離策略:線程池隔離(Bulkhead Pattern)和信號量隔離借笙,其中最推薦也是最常用的是線程池隔離。Hystrix 的線程池隔離針對不同的資源分別創(chuàng)建不同的線程池较锡,不同服務(wù)調(diào)用都發(fā)生在不同的線程池中业稼,在線程池排隊、超時等阻塞情況時可以快速失敗蚂蕴,并可以提供 fallback 機制低散。線程池隔離的好處是隔離度比較高俯邓,可以針對某個資源的線程池去進行處理而不影響其它資源,但是代價就是線程上下文切換的 overhead 比較大熔号,特別是對低延時的調(diào)用有比較大的影響稽鞭。
但是,實際情況下引镊,線程池隔離并沒有帶來非常多的好處朦蕴。最直接的影響,就是會讓機器資源碎片化祠乃∶沃兀考慮這樣一個常見的場景,在 Tomcat 之類的 Servlet 容器使用 Hystrix亮瓷,本身 Tomcat 自身的線程數(shù)目就非常多了(可能到幾十或一百多)琴拧,如果加上 Hystrix 為各個資源創(chuàng)建的線程池,總共線程數(shù)目會非常多(幾百個線程)嘱支,這樣上下文切換會有非常大的損耗蚓胸。另外,線程池模式比較徹底的隔離性使得 Hystrix 可以針對不同資源線程池的排隊除师、超時情況分別進行處理沛膳,但這其實是超時熔斷和流量控制要解決的問題,如果組件具備了超時熔斷和流量控制的能力汛聚,線程池隔離就顯得沒有那么必要了锹安。
Hystrix 的信號量隔離限制對某個資源調(diào)用的并發(fā)數(shù)。這樣的隔離非常輕量級倚舀,僅限制對某個資源調(diào)用的并發(fā)數(shù)叹哭,而不是顯式地去創(chuàng)建線程池,所以 overhead 比較小痕貌,但是效果不錯风罩。但缺點是無法對慢調(diào)用自動進行降級,只能等待客戶端自己超時舵稠,因此仍然可能會出現(xiàn)級聯(lián)阻塞的情況超升。
Sentinel 可以通過并發(fā)線程數(shù)模式的流量控制來提供信號量隔離的功能。并且結(jié)合基于響應(yīng)時間的熔斷降級模式哺徊,可以在不穩(wěn)定資源的平均響應(yīng)時間比較高的時候自動降級室琢,防止過多的慢調(diào)用占滿并發(fā)數(shù),影響整個系統(tǒng)落追。
3研乒、熔斷降級的對比
Sentinel 和 Hystrix 的熔斷降級功能本質(zhì)上都是基于熔斷器模式(Circuit Breaker Pattern)。Sentinel 與 Hystrix 都支持基于失敗比率(異常比率)的熔斷降級淋硝,在調(diào)用達到一定量級并且失敗比率達到設(shè)定的閾值時自動進行熔斷雹熬,此時所有對該資源的調(diào)用都會被 block宽菜,直到過了指定的時間窗口后才啟發(fā)性地恢復(fù)。上面提到過竿报,Sentinel 還支持基于平均響應(yīng)時間的熔斷降級铅乡,可以在服務(wù)響應(yīng)時間持續(xù)飆高的時候自動熔斷,拒絕掉更多的請求烈菌,直到一段時間后才恢復(fù)阵幸。這樣可以防止調(diào)用非常慢造成級聯(lián)阻塞的情況。
4芽世、實時指標統(tǒng)計實現(xiàn)的對比
Hystrix 和 Sentinel 的實時指標數(shù)據(jù)統(tǒng)計實現(xiàn)都是基于滑動窗口的挚赊。Hystrix 1.5 之前的版本是通過環(huán)形數(shù)組實現(xiàn)的滑動窗口,通過鎖配合 CAS 的操作對每個桶的統(tǒng)計信息進行更新济瓢。Hystrix 1.5 開始對實時指標統(tǒng)計的實現(xiàn)進行了重構(gòu)荠割,將指標統(tǒng)計數(shù)據(jù)結(jié)構(gòu)抽象成了響應(yīng)式流(reactive stream)的形式,方便消費者去利用指標信息旺矾。同時底層改造成了基于 RxJava 的事件驅(qū)動模式蔑鹦,在服務(wù)調(diào)用成功/失敗/超時的時候發(fā)布相應(yīng)的事件,通過一系列的變換和聚合最終得到實時的指標統(tǒng)計數(shù)據(jù)流箕宙,可以被熔斷器或 Dashboard 消費嚎朽。
Sentinel 目前抽象出了 Metric 指標統(tǒng)計接口,底層可以有不同的實現(xiàn)柬帕,目前默認的實現(xiàn)是基于
LeapArray
的滑動窗口哟忍,后續(xù)根據(jù)需要可能會引入 reactive stream 等實現(xiàn)。
三陷寝、Sentinel 特性
除了之前提到的兩者的共同特性之外魁索,Sentinel 還提供以下的特色功能:
1、輕量級盼铁、高性能
Sentinel 作為一個功能完備的高可用流量管控組件,其核心 sentinel-core
沒有任何多余依賴尝偎,打包后只有不到 200 KB饶火,非常輕量級。開發(fā)者可以放心地引入 sentinel-core
而不需擔心依賴問題致扯。同時肤寝,Sentinel 提供了多種擴展點,用戶可以很方便地根據(jù)需求去進行擴展抖僵,并且無縫地切合到 Sentinel 中鲤看。
引入 Sentinel 帶來的性能損耗非常小。只有在業(yè)務(wù)單機量級超過 25W QPS 的時候才會有一些顯著的影響(5% - 10% 左右)耍群,單機 QPS 不太大的時候損耗幾乎可以忽略不計义桂。
2找筝、流量控制
Sentinel 可以針對不同的調(diào)用關(guān)系,以不同的運行指標(如 QPS慷吊、并發(fā)調(diào)用數(shù)袖裕、系統(tǒng)負載等)為基準,對資源調(diào)用進行流量控制溉瓶,將隨機的請求調(diào)整成合適的形狀急鳄。
Sentinel 支持多樣化的流量整形策略,在 QPS 過高的時候可以自動將流量調(diào)整成合適的形狀堰酿。常用的有:
直接拒絕模式:即超出的請求直接拒絕疾宏。
慢啟動預(yù)熱模式:當流量激增的時候,控制流量通過的速率触创,讓通過的流量緩慢增加坎藐,在一定時間內(nèi)逐漸增加到閾值上限,給冷系統(tǒng)一個預(yù)熱的時間嗅榕,避免冷系統(tǒng)被壓垮顺饮。
-
勻速器模式:利用 Leaky Bucket 算法實現(xiàn)的勻速模式,嚴格控制了請求通過的時間間隔凌那,同時堆積的請求將會排隊兼雄,超過超時時長的請求直接被拒絕帽蝶。Sentinel 還支持基于調(diào)用關(guān)系的限流赦肋,包括基于調(diào)用方限流、基于調(diào)用鏈入口限流励稳、關(guān)聯(lián)流量限流等佃乘,依托于 Sentinel 強大的調(diào)用鏈路統(tǒng)計信息,可以提供精準的不同維度的限流驹尼。
目前 Sentinel 對異步調(diào)用鏈路的支持還不是很好趣避,后續(xù)版本會著重改善支持異步調(diào)用。
3新翎、系統(tǒng)負載保護
Sentinel 對系統(tǒng)的維度提供保護程帕,負載保護算法借鑒了 TCP BBR 的思想。當系統(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)處理最多的請求。
4蹦掐、實時監(jiān)控和控制面板
Sentinel 提供 HTTP API 用于獲取實時的監(jiān)控信息技羔,如調(diào)用鏈路統(tǒng)計信息、簇點信息卧抗、規(guī)則信息等藤滥。如果用戶正在使用 Spring Boot/Spring Cloud 并使用了Sentinel Spring Cloud Starter,還可以方便地通過其暴露的 Actuator Endpoint 來獲取運行時的一些信息社裆,如動態(tài)規(guī)則等拙绊。未來 Sentinel 還會支持標準化的指標監(jiān)控 API,可以方便地整合各種監(jiān)控系統(tǒng)和可視化系統(tǒng)泳秀,如 Prometheus标沪、Grafana 等。
Sentinel控制臺(Dashboard)提供了機器發(fā)現(xiàn)嗜傅、配置規(guī)則金句、查看實時監(jiān)控、查看調(diào)用鏈路信息等功能吕嘀,使得用戶可以非常方便地去查看監(jiān)控和進行配置违寞。
5、生態(tài)
Sentinel 目前已經(jīng)針對 Servlet偶房、Dubbo趁曼、Spring Boot/Spring Cloud、gRPC 等進行了適配棕洋,用戶只需引入相應(yīng)依賴并進行簡單配置即可非常方便地享受 Sentinel 的高可用流量防護能力挡闰。未來 Sentinel 還會對更多常用框架進行適配,并且會為 Service Mesh 提供集群流量防護的能力掰盘。
四摄悯、總結(jié)