1、基本介紹
進一步解釋說明:
- 資源名:唯一名稱,默認請求路徑。
- 針對來源:Sentinel可以針對調用者進行限流,填寫微服務名,默認default(不區分來源)。
- 閾值類型/單機閾值:
(1)QPS(每秒鍾的請求數量)︰當調用該API的QPS達到閾值的時候,進行限流。
(2)線程數:當調用該API的線程數達到閾值的時候,進行限流。
- 是否集群:不需要集群。
- 流控模式:
(1)直接:API達到限流條件時,直接限流。
(2)關聯:當關聯的資源達到閾值時,就限流自己。
(3)鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就進行限流)【API級別的針對來源】。
- 流控效果:
(1)快速失敗:直接失敗,拋異常。
(2)Warm up:根據Code Factor(冷加載因子,默認3)的值,從閾值/codeFactor,經過預熱時長,才達到設置的QPS閾值。
(3)排隊等待:勻速排隊,讓請求以勻速的速度通過,閾值類型必須設置為QPS,否則無效。
2、Sentinel流控-QPS直接失敗
直接 -> 快速失敗(系統默認)
配置及說明
表示1秒鍾內查詢1次就是OK,若超過次數1,就直接->快速失敗,報默認錯誤
測試
快速多次點擊訪問http://localhost:8401/testA
結果
返回頁面 Blocked by Sentinel (flow limiting)
源碼
com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
思考
直接調用默認報錯信息,技術方面OK,但是,是否應該有我們自己的后續處理?類似有個fallback的兜底方法?
3、Sentinel流控-線程數直接失敗
線程數:當調用該API的線程數達到閾值的時候,進行限流。
4、Sentinel流控-關聯
是什么?
-
當自己關聯的資源達到閾值時,就限流自己
-
當與A關聯的資源B達到閥值后,就限流A自己(B惹事,A掛了)
設置testA
當關聯資源/testB的QPS閥值超過1時,就限流/testA的Rest訪問地址,當關聯資源到閾值后限制配置好的資源名。
5、Sentinel流控-預熱
默認coldFactor為3,即請求QPS 從 threshold / 3開始,經預熱時長逐漸升至設定的QPS閾值。
WarmUp配置
案例,閥值為10+預熱時長設置5秒。
系統初始化的閥值為10/ 3約等於3,即閥值剛開始為3;然后過了5秒后閥值才慢慢升高恢復到10
測試
多次快速點擊http://localhost:8401/testB - 剛開始不行,后續慢慢OK
應用場景
如:秒殺系統在開啟的瞬間,會有很多流量上來,很有可能把系統打死,預熱方式就是把為了保護系統,可慢慢的把流量放進來,慢慢的把閥值增長到設置的閥值。
6、Sentinel流控-排隊等待
勻速排隊,讓請求以均勻的速度通過,閥值類型必須設成QPS,否則無效。
設置:/testA每秒1次請求,超過的話就排隊等待,等待的超時時間為20000毫秒。
勻速排隊
勻速排隊(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式會嚴格控制請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應的是漏桶算法。詳細文檔可以參考 流量控制 - 勻速器模式,具體的例子可以參見 PaceFlowDemo。
該方式的作用如下圖所示:
這種方式主要用於處理間隔性突發的流量,例如消息隊列。想象一下這樣的場景,在某一秒有大量的請求到來,而接下來的幾秒則處於空閑狀態,我們希望系統能夠在接下來的空閑期間逐漸處理這些請求,而不是在第一秒直接拒絕多余的請求。
注意:勻速排隊模式暫時不支持 QPS > 1000 的場景。
這種方式主要用於處理間隔性突發的流量,例如消息隊列。想象一下這樣的場景,在某一秒有大量的請求到來,而接下來的幾秒則處於空閑狀態,我們希望系統能夠在接下來的空閑期間逐漸處理這些請求,而不是在第一秒直接拒絕多余的請求。
注意:勻速排隊模式暫時不支持 QPS > 1000 的場景。
測試
添加日志記錄代碼到FlowLimitController的testA方法
@RestController @Slf4j public class FlowLimitController { @GetMapping("/testA") public String testA() { log.info(Thread.currentThread().getName()+"\t"+"...testA");//<---- return "------testA"; } ... }
Postman模擬並發密集訪問testA。具體操作參考117_Sentinel流控-關聯
7、Sentinel降級簡介
熔斷降級概述
除了流量控制以外,對調用鏈路中不穩定的資源進行熔斷降級也是保障高可用的重要措施之一。一個服務常常會調用別的模塊,可能是另外的一個遠程服務、數據庫,或者第三方 API 等。例如,支付的時候,可能需要遠程調用銀聯提供的 API;查詢某個商品的價格,可能需要進行數據庫查詢。然而,這個被依賴服務的穩定性是不能保證的。如果依賴的服務出現了不穩定的情況,請求的響應時間變長,那么調用服務的方法的響應時間也會變長,線程會產生堆積,最終可能耗盡業務自身的線程池,服務本身也變得不可用。
現代微服務架構都是分布式的,由非常多的服務組成。不同服務之間相互調用,組成復雜的調用鏈路。以上的問題在鏈路調用中會產生放大的效果。復雜鏈路上的某一環不穩定,就可能會層層級聯,最終導致整個鏈路都不可用。因此我們需要對不穩定的弱依賴服務調用進行熔斷降級,暫時切斷不穩定調用,避免局部不穩定因素導致整體的雪崩。熔斷降級作為保護自身的手段,通常在客戶端(調用端)進行配置。
- RT(平均響應時間,秒級)
- 平均響應時間 超出閾值 且 在時間窗口內通過的請求>=5,兩個條件同時滿足后觸發降級。
- 窗口期過后關閉斷路器。
- RT最大4900(更大的需要通過-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)。
- 異常比列(秒級)
- QPS >= 5且異常比例(秒級統計)超過閾值時,觸發降級;時間窗口結束后,關閉降級 。
- 異常數(分鍾級)
- 異常數(分鍾統計)超過閾值時,觸發降級;時間窗口結束后,關閉降級
Sentinel熔斷降級會在調用鏈路中某個資源出現不穩定狀態時(例如調用超時或異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其它的資源而導致級聯錯誤。
當資源被降級后,在接下來的降級時間窗口之內,對該資源的調用都自動熔斷(默認行為是拋出 DegradeException)。
Sentinei的斷路器是沒有類似Hystrix半開狀態的。(Sentinei 1.8.0 已有半開狀態)
半開的狀態系統自動去檢測是否請求有異常,沒有異常就關閉斷路器恢復使用,有異常則繼續打開斷路器不可用。
8、Sentinel降級-RT
是什么?
平均響應時間(DEGRADE_GRADE_RT):當1s內持續進入5個請求,對應時刻的平均響應時間(秒級)均超過閾值( count,以ms為單位),那么在接下的時間窗口(DegradeRule中的timeWindow,以s為單位)之內,對這個方法的調用都會自動地熔斷(拋出DegradeException )。注意Sentinel 默認統計的RT上限是4900 ms,超出此閾值的都會算作4900ms,若需要變更此上限可以通過啟動配置項-Dcsp.sentinel.statistic.max.rt=xxx來配置。
注意:Sentinel 1.7.0才有平均響應時間(DEGRADE_GRADE_RT
),Sentinel 1.8.0的沒有這項,取而代之的是慢調用比例 (SLOW_REQUEST_RATIO
)。
慢調用比例 (SLOW_REQUEST_RATIO):選擇以慢調用比例作為閾值,需要設置允許的慢調用 RT(即最大的響應時間),請求的響應時間大於該值則統計為慢調用。當單位統計時長(statIntervalMs)內請求數目大於設置的最小請求數目,並且慢調用的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求響應時間小於設置的慢調用 RT 則結束熔斷,若大於設置的慢調用 RT 則會再次被熔斷。
接下來講解Sentinel 1.7.0的。
測試
代碼
@RestController @Slf4j public class FlowLimitController { ... @GetMapping("/testD") public String testD() { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } log.info("testD 測試RT"); } }
配置
jmeter壓測
結論
按照上述配置,永遠一秒鍾打進來10個線程(大於5個了)調用testD,我們希望200毫秒處理完本次任務,如果超過200毫秒還沒處理完,在未來1秒鍾的時間窗口內,斷路器打開(保險絲跳閘)微服務不可用,保險絲跳閘斷電了后續我停止jmeter,沒有這么大的訪問量了,斷路器關閉(保險絲恢復),微服務恢復OK。
9、Sentinel降級-異常比例
是什么?
異常比例(DEGRADE_GRADE_EXCEPTION_RATIO):當資源的每秒請求量 >= 5,並且每秒異常總數占通過量的比值超過閾值( DegradeRule中的 count)之后,資源進入降級狀態,即在接下的時間窗口( DegradeRule中的timeWindow,以s為單位)之內,對這個方法的調用都會自動地返回。異常比率的閾值范圍是[0.0, 1.0],代表0% -100%
注意:與Sentinel 1.8.0相比,有些不同(Sentinel 1.8.0才有的半開狀態),Sentinel 1.8.0的如下:
異常比例 (ERROR_RATIO):當單位統計時長(statIntervalMs)內請求數目大於設置的最小請求數目,並且異常的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。
接下來講解Sentinel 1.7.0的。
測試
代碼
@RestController @Slf4j public class FlowLimitController { ... @GetMapping("/testD") public String testD() { log.info("testD 異常比例"); int age = 10/0; return "------testD"; } }
配置
jmeter
結論
按照上述配置,單獨訪問一次,必然來一次報錯一次(int age = 10/0),調一次錯一次。
開啟jmeter后,直接高並發發送請求,多次調用達到我們的配置條件了。斷路器開啟(保險絲跳閘),微服務不可用了,不再報錯error而是服務降級了。
10、Sentinel降級-異常數
是什么?
異常數( DEGRADE_GRADF_EXCEPTION_COUNT ):當資源近1分鍾的異常數目超過閾值之后會進行熔斷。注意由於統計時間窗口是分鍾級別的,若timeWindow小於60s,則結束熔斷狀態后碼可能再進入熔斷狀態。
注意:與Sentinel 1.8.0相比,有些不同(Sentinel 1.8.0才有的半開狀態),Sentinel 1.8.0的如下:
異常數 (ERROR_COUNT):當單位統計時長內的異常數目超過閾值之后會自動進行熔斷。經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷。
接下來講解Sentinel 1.7.0的。
異常數是按照分鍾統計的,時間窗口一定要大於等於60秒。
測試
代碼
@RestController @Slf4j public class FlowLimitController{ ... @GetMapping("/testE") public String testE() { log.info("testE 測試異常數"); int age = 10/0; return "------testE 測試異常數"; } }
配置
訪問http://localhost:8401/testE,第一次訪問絕對報錯,因為除數不能為零,我們看到error窗口,但是達到5次報錯后,進入熔斷后降級。
原文鏈接:https://blog.csdn.net/u011863024/article/details/114298288