Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

1、sentinel是什麼

sentinel的官方名稱叫分佈式系統的流量防衛兵。Sentinel 以流量爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。在Spring Cloud項目中最開始咱們使用的是Hystrix,目前已中止更新了。如今Spring Cloud官方推薦的是rensilience4j。固然還有咱們今天學習的sentinel。java

Sentinel 具備如下特徵:git

  • 豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量能夠承受的範圍)、消息削峯填谷、集羣流量控制、實時熔斷下游不可用應用等。
  • 完備的實時監控:Sentinel 同時提供實時的監控功能。您能夠在控制檯中看到接入應用的單臺機器秒級數據,甚至 500 臺如下規模的集羣的彙總運 行狀況。
  • 普遍的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只須要引入相應的依賴並進行簡單的配置便可快速地接入 Sentinel。
  • 完善的 SPI 擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展接口。您能夠經過實現擴展接口來快速地定製邏輯。例如定製規則管理、適配動態數據源等。

2、sentinel實現限流

2.1 安裝sentinel控制檯

這裏咱們直接下載jar包便可,下載後經過命令行啓動:github

java -jar sentinel-dashboard-1.7.2.jar
  • 默認端口:8080
  • 默認用戶名:sentinel
  • 默認密碼:sentinel

啓動成功後,咱們瀏覽器訪問http://localhost:8080,出現以下界面。spring

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

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服務接口調用狀況了。瀏覽器

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

2.3 配置限流規則

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

咱們這裏作一個簡單的規則配置:併發

  • 閥值類型:QPSapp

  • 單機閥值:2

意思就是:該接口每秒最多容許進入兩個請求。框架

點擊新增後,在流控規則裏發現了一條規則:分佈式

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

如今,咱們繼續請求3次這個接口。第三次響應的內容以下:ide

Blocked by Sentinel (flow limiting)

咱們打開控制檯發現拒絕了一條請求。

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

3、Sentinel規則介紹

不論是限流仍是降級,它都是按照某種規則進行的,下面具體介紹一下sentinel支持的幾種規則。

3.1 流控規則

流量控制,其原理是監控應用流量的QPS(每秒查詢率) 或併發線程數等指標,當達到指定的閾值時

對流量進行控制,以免被瞬時的流量高峯沖垮,從而保障應用的高可用性。

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

資源名:惟一名稱,默認是請求路徑,可自定義

針對來源:指定對哪一個微服務進行限流,默認指default,意思是不區分來源,所有限制

閾值類型/單機閾值

  • QPS(每秒請求數量): 當調用該接口的QPS達到閾值的時候,進行限流

  • 線程數:當調用該接口的線程數達到閾值的時候,進行限流

3.2 降級規則

降級規則就是當知足什麼條件時,對服務降級——即將請求轉發到另外接口上,這個接口與業務無關,只是爲了保證系統的完整性。

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

  • 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;
}
  • 添加規則

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

  • 運行效果

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

結果顯示,第一個參數被限流了,而第二個參數正常。

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)限制資源是否經過:

  • 若配置白名單,則只有請求來源位於白名單內時纔可經過;

  • 若配置黑名單,則請求來源位於黑名單時不經過,其他的請求經過。

Spring Cloud Alibaba系列(五)sentinel實現服務限流降級

流控應用: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;
    }
}

代碼示例

giteehttps://gitee.com/zhixie/spring-cloud-alibaba-learning/tree/master/sentinel-server

githubhttps://github.com/binzh303/spring-cloud-alibaba-learning/tree/master/sentinel-server

相關文章
相關標籤/搜索