SpringCloud入門實戰(9)--Sentinel(1)--簡介及基本使用


Sentinel是面向分布式服務架構的流量控制組件,主要以流量為切入點,從限流、流量整形、熔斷降級、系統負載保護、熱點防護等多個維度來幫助開發者保障微服務的穩定性。本文主要介紹Sentinel的基本使用,文中使用到的軟件版本:Sentinel 1.3.2、Spring Boot 2.2.5.RELEASE、Spring Cloud Hoxton.SR3、Java 1.8.0_191。

1、簡介

隨着微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。

1.1、Sentinel特性

1.2、Sentinel組成部分

a、核心庫(Java 客戶端)不依賴任何框架/庫,能夠運行於所有 Java 運行時環境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。
b、控制台(Dashboard)基於 Spring Boot 開發,打包后可以直接運行,不需要額外的 Tomcat 等應用容器。

2、規則

Sentinel的所有規則都可以在內存中動態地查詢及修改,修改之后立即生效。同時Sentinel也提供相關API,供您來定制自己的規則策略。Sentinel支持以下幾種規則:流量控制規則、熔斷降級規則、系統保護規則、來源訪問控制規則和熱點參數規則。

2.1、流量控制規則(FlowRule)

同一個資源可以同時有多個限流規則,檢查規則時會依次檢查。其重要屬性:

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

編碼方式定義規則:

private void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule(resourceName);
    // set limit qps to 20
    rule.setCount(20);
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setLimitApp("default");
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

2.2、熔斷降級規則(DegradeRule)

同一個資源可以同時有多個降級規則。其重要屬性:

Field 說明 默認值
resource 資源名,即規則的作用對象  
grade 熔斷策略,支持慢調用比例/異常比例/異常數策略 慢調用比例
count 慢調用比例模式下為慢調用臨界 RT(超出該值計為慢調用);異常比例/異常數模式下為對應的閾值  
timeWindow 熔斷時長,單位為 s  
minRequestAmount 熔斷觸發的最小請求數,請求數小於該值時即使異常比率超出閾值也不會熔斷(1.7.0 引入) 5
statIntervalMs 統計時長(單位為 ms),如 60*1000 代表分鍾級(1.8.0 引入) 1000 ms
slowRatioThreshold 慢調用比例閾值,僅慢調用比例模式有效(1.8.0 引入)  

編碼方式定義規則:

private 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);
}

2.3、系統保護規則(SystemRule)

Sentinel系統自適應限流從整體維度對應用入口流量進行控制,結合應用的 Load、CPU 使用率、總體平均 RT、入口 QPS 和並發線程數等幾個維度的監控指標,通過自適應的流控策略,讓系統的入口流量和系統的負載達到一個平衡,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。其重要屬性:

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

編碼方式定義規則:

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

2.4、訪問控制規則(AuthorityRule)

很多時候,我們需要根據調用方來限制資源是否通過,這時候可以使用 Sentinel 的訪問控制(黑白名單)的功能。其重要屬性:

resource:資源名,即規則的作用對象
limitApp:對應的黑名單/白名單,不同 origin 用 , 分隔,如 appA,appB
strategy:限制模式,AUTHORITY_WHITE 為白名單模式,AUTHORITY_BLACK 為黑名單模式,默認為白名單模式

編碼方式定義規則:

AuthorityRule rule = new AuthorityRule();
rule.setResource("test");
rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
rule.setLimitApp("appA,appB");
AuthorityRuleManager.loadRules(Collections.singletonList(rule));

2.5、熱點規則(ParamFlowRule)

熱點參數限流會統計傳入參數中的熱點參數,並根據配置的限流閾值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。其重要屬性類似於流量控制規則:

屬性 說明 默認值
resource 資源名,必填  
count 限流閾值,必填  
grade 限流模式 QPS 模式
durationInSec 統計窗口時間長度(單位為秒),1.6.0 版本開始支持 1s
controlBehavior 流控效果(支持快速失敗和勻速排隊模式),1.6.0 版本開始支持 快速失敗
maxQueueingTimeMs 最大排隊等待時長(僅在勻速排隊模式生效),1.6.0 版本開始支持 0ms
paramIdx 熱點參數的索引,必填,對應 SphU.entry(xxx, args) 中的參數索引位置  
paramFlowItemList 參數例外項,可以針對指定的參數值單獨設置限流閾值,不受前面 count 閾值的限制。僅支持基本類型和字符串類型  
clusterMode 是否是集群參數流控規則 false
clusterConfig 集群流控相關配置  

編碼方式定義規則: 

ParamFlowRule rule = new ParamFlowRule(resourceName)
    .setParamIdx(0)
    .setCount(5);
// 針對 int 類型的參數 PARAM_B,單獨設置限流 QPS 閾值為 10,而不是全局的閾值 5.
ParamFlowItem item = new ParamFlowItem().setObject(String.valueOf(PARAM_B))
    .setClassType(int.class.getName())
    .setCount(10);
rule.setParamFlowItemList(Collections.singletonList(item));

ParamFlowRuleManager.loadRules(Collections.singletonList(rule));

3、使用

3.1、拋出異常方式使用

SphU包含了try-catch風格的 API。用這種方式,當資源發生了限流之后會拋出 BlockException。這個時候可以捕捉異常,進行限流之后的邏輯處理。

3.1.1、引入依賴

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>1.8.0</version>
</dependency>

3.1.2、樣例

package com.inspur.demo.test;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

import java.util.ArrayList;
import java.util.List;

public class Sentinel {
    public static void main(String[] args) {
        // 配置規則.
        initFlowRules();
        test();
    }

    private static void test() {
        while(true) {
            // 1.5.0 版本開始可以直接利用 try-with-resources 特性
            Entry entry = null;
            try {
                entry = SphU.entry("HelloWorld");
                // 被保護的邏輯
                System.out.println("hello world");
                //Thread.sleep(1000 * 10);
            } catch (BlockException ex) {
                // 處理被流控的邏輯
                System.out.println("blocked!");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (entry != null) entry.exit();
            }
        }
    }

    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(10);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}

3.2、結合Spring Cloud使用

3.2.1、引入依賴

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.2.3.RELEASE</version>
</dependency>

3.2.2、注解方式使用sentinel

@SentinelResource注解用來標識資源是否被限流、降級。

package com.inspur.scdemo.server.service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;

@Service
public class SentinelService {
    @SentinelResource(value = "sentinel-test", blockHandler = "blockHandler", fallback = "fallback")
    public String test(long id) {
//        if (true) {
//            throw new RuntimeException("a");
//        }
        return "test";
    }

    /**
     * Block異常處理函數,用來處理Sentinel限流/熔斷等錯誤
     * 參數最后多一個BlockException,其余與原函數一致
     */
    public String blockHandler(long id, BlockException e) {
        e.printStackTrace();
        return "blockHandler";
    }

    /**
     * Fallback函數,用來處理接口中業務代碼所有異常
     * 函數簽名與原函數一致或加一個 Throwable 類型的參數.
     */
    public String fallback(long id) {
        return "fallback";
    }
}
package com.inspur.scdemo.server.controller;

import com.inspur.scdemo.server.service.SentinelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sentinel")
public class SentinelController {
    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private SentinelService service;

    @RequestMapping("/test")
    public String test(long id) {
        logger.info(id + "");

        return service.test(id);
    }

    @RequestMapping("/test2")
    public String test2(long id) {
        logger.info(id + "");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "test2";
    }
}

一般推薦將@SentinelResource注解加到服務實現上,而在Web層可以在snetinel控制台查看url並定義規則。

3.2.3、sentinel控制台

Sentinel控制台提供一個輕量級的控制台,它提供機器發現、單機資源實時監控、集群資源匯總,以及規則管理的功能。直接使用Spring Cloud Alibaba自帶的Web埋點適配。

a、下載控制台的安裝包

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

b、啟動

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

c、控制台

http://10.49.196.10:8080/   用戶名/密碼為:sentinel/sentinel

3.2.4、SpingCloud應用中配置Sentinel控制台地址

spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: 10.49.196.10:8080

project:
  name: scdemo-server

啟動應用后並訪問響應的url,sentinel控制台會出現監控信息:

 可以在對應的url后定義流控規則:

 定義降級規則:

 


免責聲明!

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



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