SpringCloud接入Sentinel進行簡單限流和熔斷

一、Sentinel簡介

    隨着微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 是面向分佈式服務架構的輕量級流量控制組件,主要以流量爲切入點,從限流、流量整形、熔斷降級、系統負載保護等多個維度來幫助您保障微服務的穩定性。

主要特性:

Sentinel-features-overview

二、安裝Sentinel控制檯

下載鏈接:https://github.com/alibaba/Sentinel/releases/tag/1.7.0 選擇sentinel-dashboard-1.7.0.jar下載

進去jar包目錄啓動:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.0.jar

默認用戶名密碼爲:sentinel sentinel

二、項目示例

此項目以2.1.1版本Spring-cloud + Dubbo + Nacos初試環境爲基礎。

實現功能:簡單限流、熔斷,Nacos動態配置限流規則

1、 添加依賴

provider 項目添加依賴:

 <!--sentinel依賴 2.1.1 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--sentinel-nacos 1.7.0 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

2、nacos新增限流規則配置

[
    {
        "resource": "test",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

新建配置選擇json格式 

配置文件解釋:

  • resource:資源名,即限流規則的作用對象
  • limitApp:流控針對的調用來源,若爲 default 則不區分調用來源
  • grade:限流閾值類型(QPS 或併發線程數);0代表根據併發數量來限流,1代表根據QPS來進行流量控制
  • count:限流閾值
  • strategy:調用關係限流策略
  • controlBehavior:流量控制效果(直接拒絕、Warm Up、勻速排隊)
  • clusterMode:是否爲集羣模式

3、配置文件修改

修改provider項目的bootstrap.yml

spring:
  application:
    name: @artifactId@
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
      datasource:
        ds:
          nacos:
            server-addr: http://*****
            groupId: DEFAULT_GROUP
            dataId: provider-sentinel
            namespace: 725d62dc-11f8-451d-ac7e-04427536de08
            rule-type: flow
  • sentinel.transport.dashboard: sentinel控制檯地址
  • server-addr:nacos地址
  • groupId:規則配置的group
  • dataId:  規則配置的dataId
  • namespace: 命名空間(有多個namespace時必須有namespace配置,否則限流規則失敗)
  • rule-type:規則類型,flow:限流規則

4、接口修改(基於註解)

try-catch風格的API可以實現限流,但是對代碼侵入性太高,推薦使用註解的方式來實現;Sentinel API 方式可在王芳文檔中查看。

注意:註解方式埋點不支持 private 方法。

@SentinelResource註解:用於定義資源,對有該註解的接口進行流量控制和熔斷

@SentinelResource(value = "test",
            blockHandler = "handleException",
            blockHandlerClass = {ExceptionUtil.class},
            fallback = "helloFallback",
            fallbackClass = {ExceptionUtil.class})
    @Override
    public Result get(String s) {
        //測試熔斷
//        throw new RuntimeException();
        return new Result(s);
    }
ExceptionUtil 
public class ExceptionUtil {

    public static Result handleException(String s, BlockException ex) {
        // Do some log here.
//        ex.printStackTrace();
        System.out.println("被限流,無法訪問接口");
        return new Result("被限流,無法訪問接口");
    }

    /**
     * 方法參數列表需要和原函數一致,或者可以額外多一個 Throwable 類型的參數用於接收對應的異常。
     * fallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 fallbackClass 爲對應的類的 Class 對象,注意對應的函數必需爲 static 函數,否則無法解析。
     *
     * @param s
     * @return
     */
    public static Result helloFallback(String s) {
        System.out.println("熔斷功能被開啓");
        return new Result("熔斷功能被開啓");
    }
}

@SentinelResource 註解包含以下屬性:

  • value:資源名稱,必需項(不能爲空)
  • entryType:entry 類型,可選項(默認爲 EntryType.OUT
  • blockHandler / blockHandlerClassblockHandler 對應處理 BlockException 的函數名稱,可選項。blockHandler 函數訪問範圍需要是 public返回類型需要與原方法相匹配,參數類型需要和原方法相匹配並且最後加一個額外的參數,類型爲 BlockException。blockHandler 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 blockHandlerClass 爲對應的類的 Class 對象,注意對應的函數必需爲 static 函數,否則無法解析。
  • fallback:fallback 函數名稱,可選項,用於在拋出異常的時候提供 fallback 處理邏輯。fallback 函數可以針對所有類型的異常(除了 exceptionsToIgnore 裏面排除掉的異常類型)進行處理。fallback 函數簽名和位置要求:
    • 返回值類型必須與原函數返回值類型一致;
    • 方法參數列表需要和原函數一致,或者可以額外多一個 Throwable 類型的參數用於接收對應的異常。
    • fallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 fallbackClass 爲對應的類的 Class 對象,注意對應的函數必需爲 static 函數,否則無法解析。
  • defaultFallback(since 1.6.0):默認的 fallback 函數名稱,可選項,通常用於通用的 fallback 邏輯(即可以用於很多服務或方法)。默認 fallback 函數可以針對所有類型的異常(除了 exceptionsToIgnore 裏面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。defaultFallback 函數簽名要求:
    • 返回值類型必須與原函數返回值類型一致;
    • 方法參數列表需要爲空,或者可以額外多一個 Throwable 類型的參數用於接收對應的異常。
    • defaultFallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 fallbackClass 爲對應的類的 Class 對象,注意對應的函數必需爲 static 函數,否則無法解析。
  • exceptionsToIgnore(since 1.6.0):用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣拋出。

注:1.6.0 之前的版本 fallback 函數只針對降級異常(DegradeException)進行處理,不能針對業務異常進行處理

特別地,若 blockHandler 和 fallback 都進行了配置,則被限流降級而拋出 BlockException 時只會進入 blockHandler 處理邏輯。若未配置 blockHandlerfallback 和 defaultFallback,則被限流降級時會將 BlockException 直接拋出(若方法本身未定義 throws BlockException 則會被 JVM 包裝一層 UndeclaredThrowableException)。

5、驗證

1、驗證限流

順序啓動provider和consumer,觀察sentinel控制檯

查看流控規則,發現配置中心的流控規則被加載到了provider

請求接口http://localhost:8003/snaPup/get  快速刷新時會被限流

2、驗證熔斷

請求接口發現:

三、參考文檔

Sentinel官方文檔

https://blog.csdn.net/qq_38157516/article/details/100122519

https://blog.csdn.net/noaman_wgs/article/details/103328793

完整代碼:https://github.com/menglinjie/spring-cloud-alibaba-example

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章