Spring Cloud Alibaba Sentinel 限流實例

什麼是Sentinel

Sentinel是阿里巴巴開源的分佈式系統的流量防衛組件,Sentinel 把流量作爲切入點,從流量控制,熔斷降級,系統負載保護等多個維度保護服務的穩定性。

Sentinel 具有以下特徵

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

Sentinel 的主要特性

安裝Sentinel

1、下載Sentinel控制檯:

所有Sentinel版本的jar包下載地址:https://github.com/alibaba/Sentinel/releases

阿里sentinel github地址:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md

2、啓動sentinel

到達指定目錄後,輸入java -jar sentinel-dashboard.jar,啓動默認爲8080端口

3、訪問控制檯

在瀏覽器上輸入 http://localhost:8080  如果sentinel是1.6.0版本需要進行登錄,默認賬號:sentinel,密碼:sentinel

輸入地址後,顯示如下圖說明控制檯啓動成功:

 

編寫sentinel實例

1、添加pom依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>0.9.0.RELEASE</version>
</dependency>

2、application.properties文件添加相應的配置信息

server.port=9977
#應用名稱,在限流的控制檯中顯示
spring.application.name=sentinel-example
#限流控制檯的地址和端口
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true

3、添加SentinelResource註解和創建對應的blockHandler類文件

SentinelTestController.java 

package com.example.wlztest.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.example.wlztest.util.SentinelExceptionUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SentinelTestController {

    @SentinelResource(value = "sentinelTest", blockHandler = "exceptionHandler"
            , blockHandlerClass = { SentinelExceptionUtil.class }
            , fallback = "fallbackHandler")
    @RequestMapping(value = "/sentinelTest",method = RequestMethod.GET)
    @ResponseBody
    public String sentinelTest(long s){

        System.out.println("執行了sentinelTest方法");
        return "執行了sentinelTest方法";
    }

    // Fallback 函數,函數簽名與原函數一致.
    public static String fallbackHandler(long s) {

        return String.format("調用了helloFallback方法", s);
    }
}

 SentinelExceptionUtil.java

package com.example.wlztest.util;

import com.alibaba.csp.sentinel.slots.block.BlockException;

public class SentinelExceptionUtil {

    //異常處理函數,參數最後多一個 BlockException,其餘與原函數一致.
    public static String exceptionHandler(long s, BlockException ex) {
        ex.printStackTrace();
        return "調用SentinelExceptionUtil中的exceptionHandler方法" + s;
    }

    public static String exceptionHandler2(String str, BlockException ex) {
        ex.printStackTrace();
        return "調用SentinelExceptionUtil中的exceptionHandler2方法 " + str;
    }
}

以下爲SentinelResource註解的屬性說明

屬性

作用

是否必填

value

資源名稱

entryType

entry類型,標記流量的方向,取值IN/OUT,默認是OUT

blockHandler

處理BlockException的函數名稱。函數要求:

1. 必須是 public

2.返回類型與原方法一致

3. 參數類型需要和原方法相匹配,並在最後加 BlockException 類型的參數。

4. 默認需和原方法在同一個類中。若希望使用其他類的函數,可配置 blockHandlerClass ,並指定blockHandlerClass裏面的方法。

blockHandlerClass

存放blockHandler的類。對應的處理函數必須static修飾,否則無法解析,其他要求:同blockHandler。

fallback

用於在拋出異常的時候提供fallback處理邏輯。fallback函數可以針對所有類型的異常(除了 exceptionsToIgnore 裏面排除掉的異常類型)進行處理。函數要求:

1. 返回類型與原方法一致

2. 參數類型需要和原方法相匹配,Sentinel 1.6開始,也可在方法最後加 Throwable 類型的參數。

3.默認需和原方法在同一個類中。若希望使用其他類的函數,可配置 fallbackClass ,並指定fallbackClass裏面的方法。

fallbackClass【1.6】

存放fallback的類。對應的處理函數必須static修飾,否則無法解析,其他要求:同fallback。

defaultFallback【1.6】

用於通用的 fallback 邏輯。默認fallback函數可以針對所有類型的異常(除了 exceptionsToIgnore 裏面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,以fallback爲準。函數要求:

1. 返回類型與原方法一致

2. 方法參數列表爲空,或者有一個 Throwable 類型的參數。

3. 默認需要和原方法在同一個類中。若希望使用其他類的函數,可配置 fallbackClass ,並指定 fallbackClass 裏面的方法。

exceptionsToIgnore【1.6】

指定排除掉哪些異常。排除的異常不會計入異常統計,也不會進入fallback邏輯,而是原樣拋出。

exceptionsToTrace

需要trace的異常

Throwable

 

通過sentinel控制檯配置限流規則

1、啓動測試工程和sentinel控制檯,可以看到下圖,控制檯中顯示當前所啓動的應用

2、點擊簇點鏈路按鈕,來到簇點鏈路的操作頁面

3、選中一個資源點擊流控按鈕,配置流控條件

4、點擊流控規則按鈕,查看規則是否正確配置

5、上圖我們將資源名爲sentinelTest的埋點配置了QPS爲3的流控條件,我們在瀏覽器訪問 http://localhost:9977/sentinelTest?s=1  ,並快速刷新多次,頁面內容由:

轉變爲:

說明成功觸發流限規則,再看主控制檯的實時監控頁面,如紅色標記,通過QPS最高爲3,符合流限規則設置:

 

以上爲使用sentinel進行流限控制的DEMO和演示流程。

Sentinel問題

1、單純使用sentinel,規則無法進行持久化,在關閉、重啓工程後,所配置的規則會丟失。需要自己進行額外的持久化操作,目前網上有一些接合Nacos或是本地文件進行規則初始化的用例。

2、使用Nacos進行規則初始化,如配置了下列依賴,會導致sentinel控制檯的規則配置失效,只能讀取Nacos中設置的規則,比較不靈活,原因是因爲當前版本的sentinel控制檯設置規則,不具備修改規則後對Nacos配置的的規則進行同步的能力。導致之後的配置新規則都需要在Nacos控制檯中進行配置,然後推送給sentinel,造成sentinel控制檯規則配合的作用下降。(此問題是本人暫無解決方法,如果有方法可以解決Sentinel控制檯同步修改Nacos規則,麻煩給我留言)

        <!--sentinel指定nacos爲數據源 -->
        <!--<dependency>-->
            <!--<groupId>com.alibaba.csp</groupId>-->
            <!--<artifactId>sentinel-datasource-nacos</artifactId>-->
            <!--<version>1.6.0</version>-->
        <!--</dependency>-->

3、結合本地文件進行Pull ,不能保證一致性、拉取過於頻繁也可能會有性能問題等。

4、實時監控默認只能監控近6秒的數據,如果想監控長時間的數據需要自己進行改造,並進行數據持久化。

5、如果你的Sentinel控制檯原本是1.6.0之前的版本,現在改成了1.6.0,出現控制檯顯示失敗或數據異常的問題。請清除緩存,關閉瀏覽器再進行訪問,個人猜想可能是因爲1.6.0增加了登錄功能的原因。

6、目前阿里有成熟的Sentinel產品,已經解決了持久化等問題,有需要也可以進行了解和借鑑。

 

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