【SpringCloud-Alibaba系列教程】8.一文學會使用sentinel
Sentinel 介紹
隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 是面向分布式服務架構的流量控制組件,主要以流量為切入點,從流量控制、熔斷降級、系統自適應保護等多個維度來幫助您保障微服務的穩定性。
Sentinel 的歷史
2012 年,Sentinel 誕生,主要功能為入口流量控制。
2013-2017 年,Sentinel 在阿里巴巴集團內部迅速發展,成為基礎技術模塊,覆蓋了所有的核心場景。Sentinel 也因此積累了大量的流量歸整場景以及生產實踐。
2018 年,Sentinel 開源,并持續演進。
2019 年,Sentinel 朝著多語言擴展的方向不斷探索,推出 C++ 原生版本,同時針對 Service Mesh 場景也推出了 Envoy 集群流量控制支持,以解決 Service Mesh 架構下多語言限流的問題。
2020 年,推出 Sentinel Go 版本,繼續朝著云原生方向演進。
2021 年,Sentinel 正在朝著 2.0 云原生高可用決策中心組件進行演進;同時推出了 Sentinel Rust 原生版本。
Sentinel 基本概念
1. 資源
資源是 Sentinel 的關鍵概念。它可以是 Java 應用程序中的任何內容,例如,由應用程序提供的服務,或由應用程序調用的其它應用提供的服務,甚至可以是一段代碼。在接下來的文檔中,我們都會用資源來描述代碼塊。
只要通過 Sentinel API 定義的代碼,就是資源,能夠被 Sentinel 保護起來。大部分情況下,可以使用方法簽名,URL,甚至服務名稱作為資源名來標示資源。
2. 規則
圍繞資源的實時狀態設定的規則,可以包括流量控制規則、熔斷降級規則以及系統保護規則。所有規則可以動態實時調整。
流量控制有以下幾個角度:
資源的調用關系,例如資源的調用鏈路,資源和資源之間的關系;
運行指標,例如 QPS、線程池、系統負載等;
控制的效果,例如直接限流、冷啟動、排隊等。
Sentinel 的設計理念是讓您自由選擇控制的角度,并進行靈活組合,從而達到想要的效果。
1.流控規則
首先我們看一下流控規則
我們打開sentinel面板:
啟動我們的微服務(可用上一章分支代碼)
可以看到相關的接口,下面我們進行設置點開流控
在此可以看到設置QPS為1,不斷刷新,可以看到被限流了
同樣的并發線程數也可以設置的。不太好演示就不演示了同樣可以達到限流的效果。
點開高級選項
可以看到很多的設置例如直接、關聯、鏈路。
流控效果有:快速失敗,Warm Up、排隊等待。
直接(默認):接口達到限流條件時,開啟限流。
關聯:當關聯的資源達到限流條件時,開啟限流 (適合做應用讓步)。
鏈路:當從某個接口過來的資源達到限流條件時,開啟限流。
直接流控模式
直接流控模式是最簡單的模式,當指定的接口達到限流條件時開啟限流。前面的兩個案例都是默認直接流控。
關聯流控模式
關聯流控模式指的是,當指定接口關聯的接口達到限流條件時,開啟對指定接口開啟限流。
鏈路流控模式
鏈路流控模式是指當前一個接口調用service中一個方法,另一個接口也調用service中的一個方法,當一個接口達到QPS時,進行限流,
到底啥意思呢?下面我們來實戰一下。
首先我們在Servic中添加一個message方法。并且加上如下注解
@SentinelResource(“messsage”)//名稱可以自定義
然后再yml配置中添加收斂
然后再設置中添加流控
然后不斷刷新/order/message
就可以看到報錯了。
這個就是具體鏈路流控的規則。
采坑預告,如果不是使用本系列版本,低版本可能出現配置不生效的問題,首先自己配置
@Configuration
public class FilterContextConfigSentinel {
/**
* @NOTE 在spring-cloud-alibaba v2.1.1.RELEASE及前,sentinel1.7.0及后,關閉URL PATH聚合需要通過該方式,spring-cloud-alibaba v2.1.1.RELEASE后,可以通過配置關閉:spring.cloud.sentinel.web-context-unify=false
* 手動注入Sentinel的過濾器,關閉Sentinel注入CommonFilter實例,修改配置文件中的 spring.cloud.sentinel.filter.enabled=false
* 入口資源聚合問題:https://github.com/alibaba/Sentinel/issues/1024 或 https://github.com/alibaba/Sentinel/issues/1213
* 入口資源聚合問題解決:https://github.com/alibaba/Sentinel/pull/1111
/
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/");
// 入口資源關閉聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, “false”);
registration.setName(“sentinelFilter”);
registration.setOrder(1);
return registration;
}
}
然后再yml配置進行配置
這樣所有的就顯示了
配置流控效果
快速失敗(默認): 直接失敗,拋出異常,不做任何額外的處理,是最簡單的效果
Warm Up:它從開始閾值到最大QPS閾值會有一個緩沖階段,一開始的閾值是最大QPS閾值的1/3,然后慢慢增長,直到最大閾值,適用于將突然增大的流量轉換為緩步增長的場景。
排隊等待:讓請求以均勻的速度通過,單機閾值為每秒通過數量,其余的排隊等待; 它還會讓設置一個超時時間,當請求超過超時間時間還未處理,則會被丟棄。
前面的例子都是對當前的請求服務進行流控規則的新增,而流控模式中的關聯,可以使得其它的請求服務達到閾值,本服務進行流控。
2.熔斷降級
什么是熔斷降級
除了流量控制以外,降低調用鏈路中的不穩定資源也是 Sentinel 的使命之一。由于調用關系的復雜性,如果調用鏈路中的某個資源出現了不穩定,最終會導致請求發生堆積。這個問題和 Hystrix 里面描述的問題是一樣的。
Sentinel 和 Hystrix 的原則是一致的: 當調用鏈路中某個資源出現不穩定,例如,表現為 timeout,異常比例升高的時候,則對這個資源的調用進行限制,并讓請求快速失敗,避免影響到其它的資源,最終產生雪崩的效果。
熔斷降級設計理念
在限制的手段上,Sentinel 和 Hystrix 采取了完全不一樣的方法。
Hystrix 通過線程池的方式,來對依賴(在我們的概念中對應資源)進行了隔離。這樣做的好處是資源和資源之間做到了最徹底的隔離。缺點是除了增加了線程切換的成本,還需要預先給各個資源做線程池大小的分配。
Sentinel 對這個問題采取了兩種手段:
通過并發線程數進行限制
和資源池隔離的方法不同,Sentinel 通過限制資源并發線程的數量,來減少不穩定資源對其它資源的影響。這樣不但沒有線程切換的損耗,也不需要您預先分配線程池的大小。當某個資源出現不穩定的情況下,例如響應時間變長,對資源的直接影響就是會造成線程數的逐步堆積。當線程數在特定資源上堆積到一定的數量之后,對該資源的新請求就會被拒絕。堆積的線程完成任務后才開始繼續接收請求。
通過響應時間對資源進行降級
除了對并發線程數進行控制以外,Sentinel 還可以通過響應時間來快速降級不穩定的資源。當依賴的資源出現響應時間過長后,所有對該資源的訪問都會被直接拒絕,直到過了指定的時間窗口之后才重新恢復。
系統負載保護
Sentinel 同時提供系統維度的自適應保護能力。防止雪崩,是系統防護中重要的一環。當系統負載較高的時候,如果還持續讓請求進入,可能會導致系統崩潰,無法響應。在集群環境下,網絡負載均衡會把本應這臺機器承載的流量轉發到其它的機器上去。如果這個時候其它的機器也處在一個邊緣狀態的時候,這個增加的流量就會導致這臺機器也崩潰,最后導致整個集群不可用。
針對這個情況,Sentinel 提供了對應的保護機制,讓系統的入口流量和系統的負載達到一個平衡,保證系統在能力范圍之內處理最多的請求。
下面我們開始測試,首先我們在界面設置RT為1,時間為5s
進行瘋狂刷新后就可以看到限流了,然后等待5s就可以正常的訪問了。
異常比例和異常數都是根據當前拋出異常的次數進行限流時間的,在此就不和大家演示了。
3.熱點規則
熱點規則其實就是將控制作用到參數級別上。
下面開始我們的測試,我們先新建一個帶參數的。
(這里有一個彩蛋,有一個小錯誤,改正才能在sentinel中看到相關資源,大家仔細了哦~)
進行訪問測試
在sentinel進行熱點規則配置
多次刷新就可以看到限流了
同樣我們瘋狂刷新age這邊是沒有限流的
點開高級選項,我們可以對具體的參數進行限流
這樣的意思就是通過15的1000QPS才會限流,例如14 3QPS就會限流
然后進行age不同進行刷新測試就可以了
4.授權規則
其實就是根據不同來源調用微服務的鏈路進行限流。
點開授權就是黑白名單選擇。
白名單:授權才可以進行訪問。
黑名單:在黑名單里面的都不可以訪問。
流控應用就是我們的微服務調用。
下面我們開始實戰:
首先我們開始創建這樣一個類RequestOriginParserDefinition 實現 RequestOriginParser接口
集成相關的類
public class RequestOriginParserDefinition implements RequestOriginParser {
//定義請求區分來源
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
String serviceName = httpServletRequest.getParameter(“serviceName”);
if(StringUtils.isEmpty(serviceName)){
throw new RuntimeException(“服務為空”);
}
return serviceName;
}
}
然后白名單添加pc
訪問接口攜帶pc,是沒有問題的,我們要是攜帶其他參數就會提示問題了。
這個就是授權規則了。
4.系統規則
系統保護規則是從應用級別的入口流量進行控制,從單臺機器的總體Load、RT、入口QPS、CPU使用率和線程數五個維度監控應用數據,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。
系統保護規則是從應用級別的入口流量進行控制,從單臺機器的總體Load、RT、入口QPS、CPU使用率和線程數五個維度監控應用數據,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。
系統保護規則是應用整體維度的,而不是資源維度的,并且僅對入口流量(進入應用的流量)生效。
·Load(僅對Linux/Unix-like機器生效)︰當系統load1超過閾值,且系統當前的并發線程數超過系統容量時才會觸發系統保護。系統容量由系統的maxQps * minRt計算得出。設定參考值一般是CPU cores * 2.5。·RT:當單臺機器上所有入口流星的平均RT達到閾值即觸發系統保護,單位是毫秒。
·線程數:當單臺機器上所有入口流量的并發線程數達到閾值即觸發系統保護。
·入口QPS:當單臺機器上所有入口流量的QPS達到閾值即觸發系統保護。
.CPU使用率:當單臺機器上所有入口流量的CPU使用率達到閾值即觸發系統保護。
4.自定義異常返回
在之前我們看到的異常返回都是通過本身的系統的返回,現在我們如何自定義呢?
那我們開始吧
首先新建處理異常類繼承UrlBlockHandler
然后設置流控QPS的值。
然后我們瘋狂刷新就可以看到自定義異常頁面了。
設置熔斷,和上面一樣的操作。
然后就是@SentinelResource的相關介紹
設置流控
BlockException和Throwable,都是拋出的異常,后者的范圍大一些,如果去掉BlockException
只會進入Throwable
為什么要區分兩個呢?其實就是區分到底是sentinel還是系統代碼的異常。
最后就是持久化了,默認保存在內存中的,微服務重新啟動,sentinel規則就不存在了,所以我們需要持久化。
持久化以及持久化到nacos可以參考https://blog.csdn.net/weixin_42654295/article/details/117455723
到此,我們這一章的sentinel實戰就完成了
后期會在這個項目上不斷添加,喜歡的請點個start~
項目源碼參考一下分支220212_xgc_useSentinel
Gitee:https://gitee.com/coderxgc/springcloud-alibaba
GitHub:https://github.com/coderxgc/springcloud-alibaba
Spring Cloud 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。