sentinel的官方名稱叫分佈式系統的流量防衛兵。Sentinel 以流量爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。在Spring Cloud項目中最開始咱們使用的是Hystrix,目前已中止更新了。如今Spring Cloud官方推薦的是rensilience4j。固然還有咱們今天學習的sentinel。java
Sentinel 具備如下特徵:git
這裏咱們直接下載jar包便可,下載後經過命令行啓動:github
java -jar sentinel-dashboard-1.7.2.jar
啓動成功後,咱們瀏覽器訪問http://localhost:8080,出現以下界面。spring
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
server: port: 7003 spring: application: name: sentinel-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848 sentinel: transport: dashboard: 127.0.0.1:8080
@SpringBootApplication public class SentinelApplication { public static void main(String[] args) { SpringApplication.run(SentinelApplication.class, args); } } @RestController class TestController{ @GetMapping("/test") public String test(){ return "hello! sentinel!"; } }
咱們請求幾回這個接口後,打開sentinel控制檯,就能夠實時監控到這個sentinel-provider服務接口調用狀況了。瀏覽器
咱們這裏作一個簡單的規則配置:併發
閥值類型:QPSapp
意思就是:該接口每秒最多容許進入兩個請求。框架
點擊新增後,在流控規則裏發現了一條規則:分佈式
如今,咱們繼續請求3次這個接口。第三次響應的內容以下:ide
Blocked by Sentinel (flow limiting)
咱們打開控制檯發現拒絕了一條請求。
不論是限流仍是降級,它都是按照某種規則進行的,下面具體介紹一下sentinel支持的幾種規則。
流量控制,其原理是監控應用流量的QPS(每秒查詢率) 或併發線程數等指標,當達到指定的閾值時
對流量進行控制,以免被瞬時的流量高峯沖垮,從而保障應用的高可用性。
資源名:惟一名稱,默認是請求路徑,可自定義
針對來源:指定對哪一個微服務進行限流,默認指default,意思是不區分來源,所有限制
閾值類型/單機閾值:
QPS(每秒請求數量): 當調用該接口的QPS達到閾值的時候,進行限流
降級規則就是當知足什麼條件時,對服務降級——即將請求轉發到另外接口上,這個接口與業務無關,只是爲了保證系統的完整性。
RT(平均響應時間) :當資源的平均響應時間超過閾值(以 ms 爲單位)以後,資源進入準降級狀態。若是接下來 1s 內持續進入 5 個請求,它們的 RT都持續超過這個閾值,那麼在接下的時間窗口(以 s 爲單位)以內,就會對這個方法進行服務降級。
注意 Sentinel 默認統計的 RT 上限是 4900 ms,超出此閾值的都會算做 4900 ms,若須要變動此上限能夠經過啓動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置。
異常比例:當資源的每秒異常總數佔經過量的比值超過閾值以後,資源進入降級狀態,即在接下的時間窗口(以 s 爲單位)以內,對這個方法的調用都會自動地返回。異常比率的閾值範圍是 [0.0,1.0]。
熱點規則容許將規則具體到參數上。
咱們用個例子來看看效果。
@GetMapping("/myTest") @SentinelResource("test3") public String test123(String name,String age){ return name + "----"+ age; }
結果顯示,第一個參數被限流了,而第二個參數正常。
系統保護規則是從應用級別的入口流量進行控制,從單臺機器的整體 Load、RT、入口 QPS 、CPU使用率和線程數五個維度監控應用數據,讓系統儘量跑在最大吞吐量的同時保證系統總體的穩定性。
系統保護規則是應用總體維度的,而不是資源維度的,而且僅對入口流量 (進入應用的流量) 生效。
Load(僅對 Linux/Unix-like 機器生效):當系統 load1 超過閾值,且系統當前的併發線程數超過系統容量時纔會觸發系統保護。系統容量由系統的 maxQps minRt 計算得出。設定參考值通常是 CPU cores 2.5。
RT:當單臺機器上全部入口流量的平均 RT 達到閾值即觸發系統保護,單位是毫秒。
線程數:當單臺機器上全部入口流量的併發線程數達到閾值即觸發系統保護。
入口 QPS:當單臺機器上全部入口流量的 QPS 達到閾值即觸發系統保護。
不少時候,咱們須要根據調用來源來判斷該次請求是否容許放行,這時候可使用 Sentinel 的來源問控制的功能。來源訪問控制根據資源的請求來源(origin)限制資源是否經過:
若配置白名單,則只有請求來源位於白名單內時纔可經過;
流控應用:sentinel提供了RequestOriginParser來處理接口來源。
咱們運行abc來源的請求訪問/test接口。
@Component class requestOrigin implements RequestOriginParser{ @Override public String parseOrigin(HttpServletRequest httpServletRequest) { String server = httpServletRequest.getParameter("server"); return server; } }
咱們請求http://localhost:7003/test?server=abc 和 http://localhost:7003/test?server=ab來分別看看效果。
@SentinelResource 用於定義資源,並提供可選的異常處理和 fallback 配置項。
主要參數有如下幾個
屬性 | 做用 |
---|---|
value | 資源名稱 |
entryType | entry類型,標記流量的方向,取值IN/OUT,默認是OUT |
blockHandler | 處理BlockException的函數名稱,函數要求:1. 必須是 public;2.返回類型 參數與原方法一致;3. 默認需和原方法在同一個類中。若但願使用其餘類的函數,可配置blockHandlerClass ,並指定blockHandlerClass裏面的方法。 |
blockHandlerClass | 存放blockHandler的類,對應的處理函數必須static修飾。 |
fallback | 1. 返回類型與原方法一致;2. 參數類型須要和原方法相匹配;3. 默認需和原方法在同一個類中。若但願使用其餘類的函數,可配置fallbackClass |
fallbackClass | 存放fallback的類。對應的處理函數必須static修飾。 |
defaultFallback | 若同時配置了 fallback 和 defaultFallback,以fallback爲準。 |
exceptionsToIgnore | 指定排除掉哪些異常。排除的異常不會計入異常統計,也不會進入fallback邏輯,而是原樣拋出。 |
exceptionsToTrace | 須要trace的異常 |
@sentinelResource可結合blockHandler用於限流處理,結合fallback用於降級處理。具體規則可經過sentinel控制檯配置,具體我就不演示了,在下一章內容中,我會分別演示限流和降級的應用。
public class MySentinelResource { @SentinelResource(value="message",blockHandler="blockHandler",fallback="fallback") public String message(String str){ if(StringUtils.isBlank(str)){ throw new RuntimeException(); } return str; } /** * 限流處理 * @param str * @param ex * @return */ public String blockHandler(String str, BlockedException ex){ return str + "--"+ ex; } /** * 降級處理 * @param str * @return */ public String fallback(String str){ return null; } }
gitee:https://gitee.com/zhixie/spring-cloud-alibaba-learning/tree/master/sentinel-server
github:https://github.com/binzh303/spring-cloud-alibaba-learning/tree/master/sentinel-server