一、sentinel是什麼 sentinel的官方名稱叫分散式系統的流量防衛兵。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。在Spring Cloud項目中最開始我們使用的是Hystrix,目前已停止更新了。現在Spring Cloud官方推薦的是 ...
一、sentinel是什麼
sentinel的官方名稱叫分散式系統的流量防衛兵。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。在Spring Cloud項目中最開始我們使用的是Hystrix,目前已停止更新了。現在Spring Cloud官方推薦的是rensilience4j。當然還有我們今天學習的sentinel。
Sentinel 具有以下特征:
- 豐富的應用場景:Sentinel 承接了阿裡巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應用等。
- 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制臺中看到接入應用的單台機器秒級數據,甚至 500 台以下規模的集群的彙總運 行情況。
- 廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴併進行簡單的配置即可快速地接入 Sentinel。
- 完善的 SPI 擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展介面。您可以通過實現擴展介面來快速地定製邏輯。例如定製規則管理、適配動態數據源等。
二、sentinel實現限流
2.1 安裝sentinel控制台
這裡我們直接下載jar包即可,下載後通過命令行啟動:
java -jar sentinel-dashboard-1.7.2.jar
- 預設埠:8080
- 預設用戶名:sentinel
- 預設密碼:sentinel
啟動成功後,我們瀏覽器訪問http://localhost:8080,出現如下界面。
2.2 微服務繼承sentinel
- 引入sentinel依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 添加sentinel的相關配置
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服務介面調用情況了。
2.3 配置限流規則
我們這裡做一個簡單的規則配置:
-
閥值類型:QPS
-
單機閥值:2
意思就是:該介面每秒最多允許進入兩個請求。
點擊新增後,在流控規則里發現了一條規則:
現在,我們繼續請求3次這個介面。第三次響應的內容如下:
Blocked by Sentinel (flow limiting)
我們打開控制台發現拒絕了一條請求。
三、Sentinel規則介紹
不管是限流還是降級,它都是按照某種規則進行的,下麵具體介紹一下sentinel支持的幾種規則。
3.1 流控規則
流量控制,其原理是監控應用流量的QPS(每秒查詢率) 或併發線程數等指標,當達到指定的閾值時
對流量進行控制,以避免被瞬時的流量高峰衝垮,從而保障應用的高可用性。
資源名:唯一名稱,預設是請求路徑,可自定義
針對來源:指定對哪個微服務進行限流,預設指default,意思是不區分來源,全部限制
閾值類型/單機閾值:
-
QPS(每秒請求數量): 當調用該介面的QPS達到閾值的時候,進行限流
-
線程數:當調用該介面的線程數達到閾值的時候,進行限流
3.2 降級規則
降級規則就是當滿足什麼條件時,對服務降級——即將請求轉發到另外介面上,這個介面與業務無關,只是為了保證系統的完整性。
-
RT(平均響應時間) :當資源的平均響應時間超過閾值(以 ms 為單位)之後,資源進入準降級狀態。如果接下來 1s 內持續進入 5 個請求,它們的 RT都持續超過這個閾值,那麼在接下的時間視窗(以 s 為單位)之內,就會對這個方法進行服務降級。
註意 Sentinel 預設統計的 RT 上限是 4900 ms,超出此閾值的都會算作 4900 ms,若需要變更此上限可以通過啟動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置。
-
異常比例:當資源的每秒異常總數占通過量的比值超過閾值之後,資源進入降級狀態,即在接下的時間視窗(以 s 為單位)之內,對這個方法的調用都會自動地返回。異常比率的閾值範圍是 [0.0,1.0]。
-
異常數 :當資源近 1 分鐘的異常數目超過閾值之後會進行服務降級。註意由於統計時間視窗是分鐘級別的,若時間視窗小於 60s,則結束熔斷狀態後仍可能再進入熔斷狀態。
3.3 熱點規則
熱點規則允許將規則具體到參數上。
我們用個例子來看看效果。
- 編寫介面
@GetMapping("/myTest")
@SentinelResource("test3")
public String test123(String name,String age){
return name + "----"+ age;
}
- 添加規則
- 運行效果
結果顯示,第一個參數被限流了,而第二個參數正常。
3.4 系統規則
系統保護規則是從應用級別的入口流量進行控制,從單台機器的總體 Load、RT、入口 QPS 、CPU使用率和線程數五個維度監控應用數據,讓系統儘可能跑在最大吞吐量的同時保證系統整體的穩定性。
系統保護規則是應用整體維度的,而不是資源維度的,並且僅對入口流量 (進入應用的流量) 生效。
-
Load(僅對 Linux/Unix-like 機器生效):當系統 load1 超過閾值,且系統當前的併發線程數超過系統容量時才會觸發系統保護。系統容量由系統的 maxQps * minRt 計算得出。設定參考值一般是 CPU cores * 2.5。
-
RT:當單台機器上所有入口流量的平均 RT 達到閾值即觸發系統保護,單位是毫秒。
-
線程數:當單台機器上所有入口流量的併發線程數達到閾值即觸發系統保護。
-
入口 QPS:當單台機器上所有入口流量的 QPS 達到閾值即觸發系統保護。
-
CPU使用率:當單台機器上所有入口流量的 CPU使用率達到閾值即觸發系統保護。
3.5 授權規則
很多時候,我們需要根據調用來源來判斷該次請求是否允許放行,這時候可以使用 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的使用
@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