SpringCloud Alibaba (三):Sentinel 流量控制組件


SpringCloud Alibaba (三):Sentinel 流量控制組件

Sentinel 是什么

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

Sentinel 基本概念

資源

資源是 Sentinel 的關鍵概念。它可以是 Java 應用程序中的任何內容,例如,由應用程序提供的服務,或由應用程序調用的其它應用提供的服務,甚至可以是一段代碼。

只要通過 Sentinel API 定義的代碼,就是資源,能夠被 Sentinel 保護起來。大部分情況下,可以使用方法簽名,URL,甚至服務名稱作為資源名來標示資源。

規則

圍繞資源的實時狀態設定的規則,可以包括流量控制規則、熔斷降級規則以及系統保護規則。所有規則可以動態實時調整。

 

規則的種類

Sentinel 的所有規則都可以在內存態中動態地查詢及修改,修改之后立即生效。同時 Sentinel 也提供相關 API,供您來定制自己的規則策略。

Sentinel 支持以下幾種規則:流量控制規則熔斷降級規則系統保護規則來源訪問控制規則熱點參數規則

流量控制規則 (FlowRule)

流量規則的定義0

重要屬性:

Field 說明 默認值
resource 資源名,資源名是限流規則的作用對象  
count 限流閾值  
grade 限流閾值類型,QPS 或線程數模式 QPS 模式
limitApp 流控針對的調用來源 default,代表不區分調用來源
strategy 調用關系限流策略:直接、鏈路、關聯 根據資源本身(直接)
controlBehavior 流控效果(直接拒絕 / 排隊等待 / 慢啟動模式),不支持按調用關系限流 直接拒絕

同一個資源可以同時有多個限流規則。

通過代碼定義流量控制規則

理解上面規則的定義之后,我們可以通過調用 FlowRuleManager.loadRules() 方法來用硬編碼的方式定義流量控制規則,比如:

private static void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule1 = new FlowRule();
    rule1.setResource(resource);
    // Set max qps to 20
    rule1.setCount(20);
    rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule1.setLimitApp("default");
    rules.add(rule1);
    FlowRuleManager.loadRules(rules);
}

更多詳細內容可以參考 流量控制

熔斷降級規則 (DegradeRule)

熔斷降級規則包含下面幾個重要的屬性:

Field 說明 默認值
resource 資源名,即限流規則的作用對象  
count 閾值  
grade 熔斷策略,支持秒級 RT/秒級異常比例/分鍾級異常數 秒級平均 RT
timeWindow 降級的時間,單位為 s  

同一個資源可以同時有多個降級規則。

理解上面規則的定義之后,我們可以通過調用 DegradeRuleManager.loadRules() 方法來用硬編碼的方式定義流量控制規則。

 private static void initDegradeRule() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource(KEY);
        // set threshold rt, 10 ms
        rule.setCount(10);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        rule.setTimeWindow(10);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

更多詳情可以參考 熔斷降級

系統保護規則 (SystemRule)

規則包含下面幾個重要的屬性:

Field 說明 默認值
highestSystemLoad load1 閾值,參考值 -1 (不生效)
avgRt 所有入口流量的平均響應時間 -1 (不生效)
maxThread 入口流量的最大並發數 -1 (不生效)
qps 所有入口資源的 QPS -1 (不生效)
highestCpuUsage 當前系統的 CPU 使用率(0.0-1.0) -1 (不生效)

理解上面規則的定義之后,我們可以通過調用 SystemRuleManager.loadRules() 方法來用硬編碼的方式定義流量控制規則。

private void initSystemProtectionRule() {
  List<SystemRule> rules = new ArrayList<>();
  SystemRule rule = new SystemRule();
  rule.setHighestSystemLoad(10);
  rules.add(rule);
  SystemRuleManager.loadRules(rules);
}

更多詳情可以參考 系統自適應保護

訪問控制規則 (AuthorityRule)

很多時候,我們需要根據調用方來限制資源是否通過,這時候可以使用 Sentinel 的訪問控制(黑白名單)的功能。黑白名單根據資源的請求來源(origin)限制資源是否通過,若配置白名單則只有請求來源位於白名單內時才可通過;若配置黑名單則請求來源位於黑名單時不通過,其余的請求通過。

授權規則,即黑白名單規則(AuthorityRule)非常簡單,主要有以下配置項:

  • resource:資源名,即限流規則的作用對象

  • limitApp:對應的黑名單/白名單,不同 origin 用 , 分隔,如 appA,appB

  • strategy:限制模式,AUTHORITY_WHITE 為白名單模式,AUTHORITY_BLACK 為黑名單模式,默認為白名單模式

更多詳情可以參考 來源訪問控制

熱點規則 (ParamFlowRule)

詳情可以參考 熱點參數限流

 

Sentinel控制台

概述

Sentinel 提供一個輕量級的開源控制台,它提供機器發現以及健康情況管理、監控(單機和集群),規則管理和推送的功能。另外,鑒權在生產環境中也必不可少。這里,我們將會詳細講述如何通過簡單的步驟就可以使用這些功能。

接下來,我們將會逐一介紹如何整合 Sentinel 核心庫和 Dashboard,讓它發揮最大的作用。同時我們也在阿里雲上提供企業級的控制台:AHAS Sentinel 控制台,您只需要幾個簡單的步驟,就能最直觀地看到控制台如何實現這些功能。

Sentinel 控制台包含如下功能:

  • 查看機器列表以及健康情況:收集 Sentinel 客戶端發送的心跳包,用於判斷機器是否在線。

  • 監控 (單機和集群聚合):通過 Sentinel 客戶端暴露的監控 API,定期拉取並且聚合應用監控信息,最終可以實現秒級的實時監控。

  • 規則管理和推送:統一管理推送規則。

  • 鑒權:生產環境中鑒權非常重要。這里每個開發者需要根據自己的實際情況進行定制。

更詳細內容,訪問 https://github.com/alibaba/Sentinel/wiki

啟動Sentinel控制台

1.在Sentinel的github上下載 sentinel-dashboard.jar

https://github.com/alibaba/Sentinel/releases

2.在sentinel-dashboard.jar所在文件夾運行cmd,在cmd里運行以下啟動命令啟動sentinel-dashboard

java -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.2.jar

3.訪問 localhost:8081,進入Sentinel控制台,默認用戶和密碼都是 sentinel

 

SpringCloud Alibaba 整合 Sentinel

Sentinel 可以簡單的分為 Sentinel 核心庫和 Dashboard。核心庫不依賴 Dashboard,但是結合 Dashboard 可以取得最好的效果。

我們說的資源,可以是任何東西,服務,服務里的方法,甚至是一段代碼。使用 Sentinel 來進行資源保護,主要分為幾個步驟:

  1. 定義資源

  2. 定義規則

  3. 檢驗規則是否生效

先把可能需要保護的資源定義好,之后再配置規則。也可以理解為,只要有了資源,我們就可以在任何時候靈活地定義各種流量控制規則。在編碼的時候,只需要考慮這個代碼是否需要保護,如果需要保護,就將之定義為一個資源。

定義資源

1. 添加依賴

注意:在整合spring-cloud-starter-alibaba-sentinelspring-cloud-starter-openfeign時,feign-core的版本要在10.1.0以上,即導入2.1.0.RELEASE或以上版本的openfeign,否則會報feign.RequestTemplate.path()Ljava/lang/String;異常,因為低版本openfeign的RequestTemplate類里沒有path方法

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>
2.添加配置
server:
  port: 8080
​
spring:
  application:
    name: consumer-8080
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.11.132:8848
    sentinel:
      transport:
        dashboard: localhost:8081 # 將服務注冊到sentinel控制台
​
feign:
  sentinel:
    enabled: true #開啟feign的sentinel支持
​
management:
  endpoints:
    web:
      exposure:
        include: "*"
3.在controller需要保護的方法添加 @SentinelResource 注解,把方法定義為資源
@RestController
public class FeignController {
​
    @Autowired
    private EchoService echoService;
    
    @SentinelResource(value = "echo", blockHandler = "echoBlockHandler", blockHandlerClass = EchoServiceBlockHandler.class)
    @GetMapping("/feign/echo/{string}")
    public String echo(@PathVariable("string")String string){
        return echoService.echo(string);
    }
​
}

@SentinelResource 用於定義資源,並提供可選的異常處理和 fallback 配置項。 @SentinelResource 注解包含以下屬性:

  • value:資源名稱,必需項(不能為空)

  • entryType:entry 類型,可選項(默認為 EntryType.OUT

  • blockHandler / blockHandlerClass: blockHandler 對應處理 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 邏輯中,而是會原樣拋出。

blockHandler 和 fallback區別

blockHandler 函數會在原方法被限流/降級/系統保護的時候調用,而 fallback 函數會針對所有類型的異常。

如果一個資源同時對 blockHandler 和 fallback 都進行了配置,除了流量控制規則觸發時拋出的 BlockException 會進入 blockHandler 處理邏輯,其他規則觸發時都會進入fallback處理邏輯

4.創建EchoServiceBlockHandler類,建立blockHandler 處理邏輯
public class EchoServiceBlockHandler {
​
    private final static Logger logger = LoggerFactory.getLogger(EchoServiceBlockHandler.class);
​
    public static String echoBlockHandler(String string, BlockException e){
        logger.error("error: "+e);
        return "方法請求降級中";
    }
​
}

在應用程序里定義規則

1.在啟動類中定義規則,並加入容器中
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Consumer8080 {
    public static void main(String[] args) {
        SpringApplication.run(Consumer8080.class, args);
    }
​
    @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }
​
    //流量控制規則
    @Bean
    public static void initFlowRule(){
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("echo"); //設置資源名,即流量控制規則的作用對象
        flowRule.setCount(2); //設置限流閾值,此為QPS,即每秒最高訪問量
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); //限流閾值類型,QPS或線程數
        rules.add(flowRule);
        FlowRuleManager.loadRules(rules);
    }
​
}
2.訪問測試

訪問 http://localhost:8080/feign/echo/hi ,快速刷新,觸發流量控制規則,調用降級邏輯

在Sentinel控制台定義規則

在Sentinel控制台上我們可以簡單、靈活地管理規則以及推送規則,但是要注意的是,在Sentinel控制台上定義的規則是不會被持久化的,僅在內存中生存,當你重啟應用時,在Sentinel控制台上定義的規則將會丟失(應用程序里定義的規則在sentinel控制台上刪除,應用重啟后會重新生效)

 

 

我的個人博客站

 

 

翻譯 朗讀 復制 正在查詢,請稍候…… 重試 朗讀 復制 復制 朗讀 復制 via 谷歌翻譯(國內)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM