sentinel 初步学习+控制台使用

零、sentinel 基本使用 - 资源与规则

资源

Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard控制台。核心库不依赖 Dashboard,但是结合 Dashboard 可以取得最好的效果。

我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用 Sentinel 来进行资源保护,主要分为几个步骤:

  1. 定义资源
  2. 定义规则
  3. 检验规则是否生效

先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。

规则

Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时 Sentinel 也提供相关 API,供您来定制自己的规则策略。Sentinel 支持以下几种规则:流量控制规则熔断降级规则系统保护规则来源访问控制规则热点参数规则

一、原生sentinel写法

sentinel有很方便的控制台可以使用,但是为了更深刻理解运行原理,还是先看看原生代码如何编写

1.引入依赖

原生的基础依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.5</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>x.y.z</version>
</dependency>

因为后期需要接入控制台,因此这里直接引入springCloud的完整依赖

        <!--cloud流控组件依赖 sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-apache-dubbo-adapter</artifactId>
            <version>1.8.5</version>
        </dependency>

这里两个依赖中,包含了基础核心依赖 sentinel-core 与注解支持依赖 sentinel-annotation-aspectj

然后就可以开始代码:

2.定义资源

资源可以是很多类型,但是经常使用的是将某个接口或者某个方法设置为资源,我们这里设置方法为资源,因为需要使用注解跟原生两种方式,所以定义两个不同的方法:

方法一:

/**
* 方法定义于 demoService 中
*/
public void sayHello() {
        System.out.println("hello!");
    }
    /**
     * 原生流控写法 - 注解方法
     */
    @GetMapping("/test")
    public void test() {
        demoService.sayHello();
    }

方法二:


    /**
     * 原生流控写法 - 耦合方法
     *
     * @return
     */
    @GetMapping("/test2")
    public String test2() {
        String str = "访问被保护的资源了。。";
        System.out.println(str);
        return null;
    }

3.编写资源控制规则

控制方式有流量控制、降级熔断、热点规则等,因为这些都可以在控制台很方便的设置,这里原生的只简单学习几个,熟悉一下代码运行规则,帮助更好的理解控制台设置的底层意义:

① 流控规则


    /**
     * 设置流控规则
     */
    private static void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        //原生耦合的 流控规则
        FlowRule flowRule = new FlowRule();
        //设置保护的资源 名称
        flowRule.setResource("sayHello");
        //设置资源保护的阈值
        flowRule.setCount(1);
        //设置限流类型 默认为 QPS
        // QPS FLOW_GRADE_QPS
        // 线程 FLOW_GRADE_THREAD
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控针对的调用来源  default 代表不区分调用来源
        flowRule.setLimitApp("default");
        //调用关系限流策略:
        // 直接 STRATEGY_DIRECT
        // 链路 STRATEGY_CHAIN
        // 关联 STRATEGY_RELATE
        flowRule.setStrategy(RuleConstant.STRATEGY_DIRECT);
        rules.add(flowRule);
        //规则集合放入
        FlowRuleManager.loadRules(rules);
    }

② 熔断降级规则


    /**
     * 设置熔断降级规则
     */
    private static void initDegradeRule() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule degradeRule = new DegradeRule();
        //资源名,即规则的作用对象
        degradeRule.setResource("sayHello");
        //熔断策略,支持
        //     慢调用比例 DEGRADE_GRADE_RT
        //     异常比例  DEGRADE_GRADE_EXCEPTION_RATIO
        //     异常数策略 DEGRADE_GRADE_EXCEPTION_COUNT
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        // 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);
        // 异常比例/异常数模式下为对应的阈值
        degradeRule.setCount(0.7);
        // 熔断时长,单位为 s
        degradeRule.setTimeWindow(10);
        //熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)
        degradeRule.setMinRequestAmount(2);
        //统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)
        degradeRule.setStatIntervalMs( 60*1000 );

        DegradeRuleManager.loadRules(rules);
    }

控制规则写完,不适用注解方式的话,需要在方法内引入规则方法,才可以生效。

在这里插入图片描述

4.对资源进行控制

①- 代码方法


    /**
     * 原生流控写法 - 耦合方法
     *
     * @return
     */
    @GetMapping("/test2")
    public String test2() {
        //引入规则
        initFlowRules();
        Entry entry = null;
        try {
            //指定被保护的资源名
            entry = SphU.entry("sayHello");
            //具体被保护的代码资源
            String str = "访问被保护的资源了。。";
            System.out.println(str);
            return str;
        } catch (BlockException e) {
            //当访问资源被限流或者降级
            //进行相应的处理
            System.out.println("被流控了");
            return "被流控了";
        } catch (Exception exception) {
            // 若需要配置流控规则,需要通过这种方式记录业务异常
            Tracer.traceEntry(exception, entry);
        } finally {
            if (entry != null) {
                entry.close();
            }
        }
        return null;
    }

②- 注解写法

在 demoService impl 方法上面添加 @SentinelResource 注解

    /**
     * 在代码资源上使用注解来实现 流控
     *
     * value : 定义资源名称,必需项(不能为空)
     *
     * blockHandler : 设置流控降级后的处理方法
     *              函数访问范围需要是 public,返回类型需要与原方法相匹配,
     *              参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException
     *              (默认该方法必须与资源声明在同一个类中)
     * blockHandlerClass : 如果需要将处理方法放在别的类中,用该注解
     *              需要指定 blockHandlerClass 为对应的类的 Class 对象,
     *              注意对应的函数必需为 static 函数,否则无法解析。
     * fallback : 用于在保护资源中抛出异常的时候提供处理逻辑;
     *             可以针对所有类型的异常进行处理,也可以排除指定的异常。
     *             函数方法的要求与流控处理的一致
     * exceptionsToIgnore : 用于指定哪些异常被排除掉,
     *             不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出.
     * fallbackClass : 作用同 blockHandlerClass
     *
     * exceptionsToIgnore : 指定那些异常不处理
     *
     * 如果同时配置了限流跟异常处理,那么先被限流,能够进入方法才交给异常处理
     */
    @Override
    @SentinelResource(value = "sayHello",
            blockHandler = "MyBlock",
            fallback = "MyFallBack",
            exceptionsToIgnore = {NullPointerException.class})
    public void sayHello() {
        System.out.println("hello!");
    }

    /**
     * 1.一定要是public方法
     * 2.返回值跟资源代码保持一致,参数也一致
     * 3.但是要多一个BlockException,可以用来区分是什么规则的处理方法
     *
     * @param e
     * @return
     */
    public void MyBlock(BlockException e) {
        e.printStackTrace();
        System.out.println("被流控了 - 注解版");

    }

    /**
     * 当保护的资源代码出现异常,交给这里处理
     * 1.返回值跟资源代码保持一致,参数也一致
     * 2.但是要多一个Throwable,可以用来区分是什么异常
     * 如果同时配置了限流跟异常处理,那么先被限流,能够进入方法才交给异常处理
     *
     * @return
     */
    public void MyFallBack(Throwable e) {
        e.printStackTrace();
        System.out.println("出现异常了 - 注解版");
    }

5.测试

对注解进行测试

正常一秒一次点击,不会出现问题,连续多次点击,超过设置的QPS,就会被流控规则捕获

在这里插入图片描述

而如果代码中出现异常,就会被异常处理方法捕获
在这里插入图片描述

如果同时设置流控跟异常处理,会先被流控,被流控放行后才会进入接口触发报错,然会再被错误处理捕获

在这里插入图片描述

代码方法雷同,不在展示

二、控制台搭配注解

1.控制台部署

Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。

Sentinel 控制台包含如下功能:

  • 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
  • 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
  • 规则管理和推送:统一管理推送规则。
  • 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。

① 下载jar包

在这里插入图片描述

② 启动

使用命令行启动

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

其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080

③ 程序接入

springBoot程序需要引入依赖,因为上面引入过 spring-cloud-starter-alibaba-sentinel 依赖,因此可以直接用

只需要在yml文件中进行配置链接

server:
  port: 7017
spring:
  profiles:
    active: dev
    #服务名
  application:
    name: service-sentinel
  cloud:
    sentinel:
      transport:
        port: 8719  # 服务占用的地址 (跟上面的 port 不是一个东西,设置为未被占用的任意端口即可,或者干脆不配置也可)
        dashboard: localhost:8080 # sentinel 地址路径

④ 使用

访问页面 http://localhost:8080 ,默认密码账号都是 sentinel

在这里插入图片描述
在这里插入图片描述

**注意:**需要访问一下接口,应用才会在控制台页面刷新出来。

2.控制台各模块介绍

① 机器列表

查看机器列表以及健康情况

当您在机器列表中看到您的机器,就代表着您已经成功接入控制台;如果没有看到您的机器,请检查配置,并通过 ${user.home}/logs/csp/sentinel-record.log.xxx 日志来排查原因

注意:请确保在使用较新版本的浏览器,我们不保证支持旧版本的浏览器。

在这里插入图片描述

② 簇点链路

展示所有可以进行资源控制的资源

簇点链路(单机调用链路)页面实时的去拉取指定客户端资源的运行情况。它一共提供两种展示模式:一种用树状结构展示资源的调用链路,另外一种则不区分调用链路展示资源的运行情况。

注意: 簇点监控是内存态的信息,它仅展示启动后调用过的资源。

在这里插入图片描述

在这里插入图片描述

③ 实时监控

同时,同一个服务下的所有机器的簇点信息会被汇总,并且秒级地展示在"实时监控"下。

注意: 实时监控仅存储 5 分钟以内的数据,如果需要持久化,需要通过调用实时监控接口来定制。

注意:请确保 Sentinel 控制台所在的机器时间与自己应用的机器时间保持一致,否则会导致拉不到实时的监控数据。

在这里插入图片描述

④ 规则管理

声明:

这里为了统一管理控制处理+异常处理,统一将全部的处理方法放入同一个 BlockHandle类 中,如无特殊声明就是放入此类中;

**注意:**处理方法+异常方法必须声明为静态的,否则访问不到

例如:


/**
 * 控制处理+异常处理
 *
 * @author byChen
 * @date 2022/8/31
 */
public class BlockHandle {
    /**
     * ===流控处理===
     */
    /**
     * 1.一定要是public方法
     * 2.返回值跟资源代码保持一致,参数也一致
     * 3.但是要多一个BlockException,可以用来区分是什么规则的处理方法
     *
     * @param e
     * @return
     */
    public static void MyQpsBlock(BlockException e) {
        e.printStackTrace();
        System.out.println("被 QPS 规则流控了");
    }

    /**
     * 当保护的资源代码出现异常,交给这里处理
     * 1.返回值跟资源代码保持一致,参数也一致
     * 2.但是要多一个Throwable,可以用来区分是什么异常
     * 如果同时配置了限流跟异常处理,那么先被限流,能够进入方法才交给异常处理
     *
     * @return
     */
    public static void MyQpsFallBack(Throwable e) {
        e.printStackTrace();
        System.out.println("出现异常了");
    }
}

1.=流控规则=

应用场景:
在这里插入图片描述

在这里插入图片描述

设置方法:

先定义资源

/**
 * 控制台使用  QPS
 */
@GetMapping("/qps")
@SentinelResource(
        value = "qps",
        blockHandlerClass = BlockHandle.class,
        blockHandler = "MyQpsBlock",
        fallbackClass = BlockHandle.class,
        fallback = "MyQpsFallBack")
public void qps() {
    System.out.println("==QPS控制==");
}

**再决定用那种流控:**QPS每秒访问数量控制 还是 并发线程控制

QPS 每秒访问数

找到对应的资源,点击 流控

在这里插入图片描述

在这里插入图片描述

新增即可;

这样每秒访问超过两次,就会触发错误处理
在这里插入图片描述

并发线程

在这里插入图片描述

超过设定的线程阈值的线程无法访问到目标资源

在这里插入图片描述

1.2 流控模式 (直接 关联 链路)

流控模式是指定统计那个方面的请求数,但最终都是对本资源来进行流控

  • 统计对当前资源的请求,达到阈值之后,对当前资源进行限流
  • 统计指定的与当前资源关联的另外一个资源,达到阈值之后,对当前资源进行限流
  • 统计从指定链路访问到本资源的请求数,达到阈值之后,对当前资源进行限流
直接

默认的就是直接,这里不再赘述

关联:

统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流;

一般是当重要的写操作请求数量过多时,就要限制一些不重要的读操作来把cpu资源让给重要的写操作;

例如:支付完成后要修改订单状态,这时候可以限制另外的对订单的读操作来保证订单状态的修改能够顺利完成

    /**
     * 修改订单状态 - 关联模式测试
     */
    @GetMapping("/write")
    @SentinelResource(
            value = "write")
    public R write() {
        System.out.println("==修改订单状态==");
        return R.ok("修改订单状态");
    }

    /**
     * 修改订单状态 - 关联模式测试
     */
    @GetMapping("/read")
    @SentinelResource(
            value = "read",
            blockHandlerClass = BlockHandle.class,
            blockHandler = "MyQpsBlock",
            fallbackClass = BlockHandle.class,
            fallback = "MyQpsFallBack")
    public R read() {
        System.out.println("====查看订单====");
        return R.ok("查看订单");
    }

使用Jmeter来模拟大量请求

使用Jmeter来请求 修改订单接口,模拟大量并发修改订单。
对 ‘查看订单‘ 接口进行关联模式的流控,关联修改订单接口,按照理论:当修改接口有大量的请求时(这里设为每秒5请求),会限制查看订单接口

测试结果:

在这里插入图片描述

在这里插入图片描述

总结:

满足下面条件可以使用关联模式

1.两个有竞争关系的资源

2.一个优先级较高,一个优先级较低(优先级高的触发阈值时(本案例的修改订单),对优先级低的限流(本案例的查看订单))

链路

只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值,如果超过,那么限制该链路对本资源的请求

例如 创建订单与查看订单都得调用查询商品接口,这就需要对查看订单的时候调用查询商品的频率做下限制,而创建订单时不做限制


    /**
     * 创建订单(需要调用查看商品接口) - 链路流控模式测试
     */
    @GetMapping("/createOrder")
    @SentinelResource(
            value = "createOrder")
    public R createOrder() {
        demoService.queryGoods("创建订单:");
        return R.ok("创建订单");
    }

    /**
     * 查询订单(需要调用查看商品接口) - 链路流控模式测试
     */
    @GetMapping("/queryOrder")
    @SentinelResource(
            value = "queryOrder",
            blockHandlerClass = BlockHandle.class,
            blockHandler = "MyQpsBlock",
            fallbackClass = BlockHandle.class,
            fallback = "MyQpsFallBack")
    public R queryOrder() {
        demoService.queryGoods("查看订单:");
        return R.ok("查看订单");
    }

测试

调用创建订单的时候,频率多少都不会被控制
调用查询订单的时候,因为针对它调用的查询商品接口做了限制,因此会被限制

1.8.5 的版本此模式没有生效,不知道为什么

1.3 流控效果 (快速失败 预热 排队等待)
快速失败

默认效果就是快速失败,这里不再赘述

预热 (针对激增流量)

预热就是程序启动初期,给程序一个缓慢适应的时间(给充分时间去将数据存入缓存),不会让大量的请求直接去请求数据库,而是经过一段时间慢慢的达到最大值,这个时候数据已经放在缓存中了,避免瞬间流量打垮数据库。具体就是刚开始把 阈值调低,不要让过多的请求访问服务器,不至于冲垮服务器,先让服务器一点一点处理,再慢慢加量

预热期间处理请求的数量如何确定呢?

**冷加载因子:**默认是3,也就是默认通过三个请求,经预热时长逐渐升至设定的QPS阈值

例如

现在有首页查询的接口,程序开服会涌入大量请求,现在针对该接口做流控,接口最大处理请求为每秒10个,但是需要在开服后3秒内慢慢达到10个处理:

    /**
     * 查看首页 - 预热流控效果测试
     */
    @GetMapping("/getUser")
    @SentinelResource(
            value = "getUser",
            blockHandlerClass = BlockHandle.class,
            blockHandler = "MyQpsBlock",
            fallbackClass = BlockHandle.class,
            fallback = "MyQpsFallBack")
    public R getUser() {
        System.out.println("查看首页");
        return R.ok("查看首页");
    }

控制台设置:
在这里插入图片描述

测试

现在启动压测,每秒10个请求(也就是最大处理数),但是因为预热的原因,会在刚开始的3秒内有被拒绝的请求,然后3秒后慢慢恢复

在这里插入图片描述

结果符合预期;

流量监控图:

在这里插入图片描述

**注意:**这里如果使用自定义处理返回,结果数不会显示红色,因为这条请求被失败方法处理了,正常返回,Jmeter不识别为错误请求,因此不是红色,但实际还是被流控了。

排队等待 (针对脉冲流量)

匀速排队方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求(削峰填谷)。

**注意:**这种方式,流控模式必须为QPS,否则不生效

它的中心思想是,以固定的间隔时间让请求通过。

计算方式是,当请求到来的时候,如果当前请求距离上个通过的请求通过的时间间隔不小于预设值(最大阈值),则让当前请求通过。

否则,计算当前请求的预期通过时间:

​ 如果该请求的预期通过时间小于规则预设的 timeout 时间(未等待超时),则该请求会等待直到预设时间到来通过(排队等待处理);

​ 若预期的通过时间超出最大排队时长(等待超时),则直接拒接这个请求

比如,每到早八点,会大量进行打卡操作,但过了点就会几乎没有请求,这样就属于脉冲流量;设置每秒处理5个,其余的慢慢等待处理,等待5秒,如果超过最长等待时间,就报错再次手动尝试。

    /**
     * 打卡 - 排队等待流控效果测试
     */
    @GetMapping("/lookPicket")
    @SentinelResource(
            value = "lookPicket")
    public R lookPicket() {
        System.out.println("打卡");
        return R.ok("打卡");
    }

控制台设置

在这里插入图片描述

测试流量

在这里插入图片描述

可以看到,脉冲流量下,都被正常处理。

2.=熔断降级规则=

在这里插入图片描述

在这里插入图片描述

2.2熔断降级模式 (慢调用比例 异常比例 异常数)
慢调用比例

在这里插入图片描述

比如,如果单位时间内,每5次请求都有1次**(5X0.2=1)**的响应时间超过两秒,就进行暂时熔断2秒,等两秒后再次尝试请求。如果请求成功就正常监控下一次熔断,如果熔断后第一次请求依旧超时,就再次进入2秒的熔断。

资源    /**
     * 查询 - 慢调用策略 熔断降级效果 测试
     * 慢调用接口,耗时两秒
     */
    @GetMapping("/lastSecond")
    @SentinelResource(
            value = "lastSecond")
    public R lastSecond() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("慢调用接口");
        return R.ok("success");
    }

控制台设置

在这里插入图片描述

测试

当Jmeter访问10次接口后,因为每一次都是慢调用,所以肯定会被降级,这时在使用postman请求接口,应该显示服务熔断降级。
而过了熔断时间后,程序接口处于半开探测状态,这时候再请求接口,接口依旧是慢调用,会再次触发熔断,又进入熔断时间。
注意:处于半开探测状态时,第一次请求接口也是会正常进入接口执行的,要不然也没有办法计算响应时间。

结果:

在这里插入图片描述

在这里插入图片描述

多次请求后超过慢调用比例,进行熔断降级,再次访问提示服务降级,与预期一致。

这时候过了熔断时间,再次访问,会在成功一次后得出现在的响应时间,因为依旧是慢调用,再次进入熔断降级

在这里插入图片描述

异常比例

大致同慢调用比例一样,也是单位时间内达到目标请求次数并且异常比例超过设置的阈值会触发降级;只不过统计的比例由慢调用比例改为接口报错的比例。

定义资源

    /**
     * 查询 - 异常比例策略 熔断降级效果 测试
     * 内部生成异常
     */
    @GetMapping("/myError")
    @SentinelResource(
            value = "myError",
            blockHandlerClass = BlockHandle.class,
            blockHandler = "MyRtBlock")
    public R myError() {
        int a = 1 / 0;
        return R.ok("success");
    }

控制台设置

在这里插入图片描述

测试

当Jmeter访问10次接口后,因为每一次都是报错,所以肯定会被降级,这时在使用postman请求接口,应该显示服务熔断降级。
而过了熔断时间后,程序接口处于半开探测状态,这时候再请求接口,接口依旧是报错,会再次触发熔断,又进入熔断时间。
注意:处于半开探测状态时,第一次请求接口也是会正常进入接口执行的,要不然也没有办法判断是否还存在错误。

结果

在这里插入图片描述

在这里插入图片描述

多次请求后超过异常比例,进行熔断降级,再次访问提示服务降级,与预期一致。

这时候过了熔断时间,再次访问,会在成功一次后进入接口,因为依旧是报错,再次进入熔断降级

在这里插入图片描述

与预期一致

异常数

大致同慢调用比例一样,也是单位时间内达到目标请求次数并且异常请求数量超过设置的阈值会触发降级;只不过统计的参数变为了错误的数量。

定义资源

    /**
     * 查询 - 异常比例策略 熔断降级效果 测试
     * 内部生成异常
     */
    @GetMapping("/myError")
    @SentinelResource(
            value = "myError",
            blockHandlerClass = BlockHandle.class,
            blockHandler = "MyRtBlock")
    public R myError() {
        int a = 1 / 0;
        return R.ok("success");
    }

控制台设置

在这里插入图片描述

测试

当访问2次接口后,因为每一次都是报错,所以肯定会被降级,这时再使用postman请求接口,应该显示服务熔断降级。
而过了熔断时间后,程序接口处于半开探测状态,这时候再请求接口,接口依旧是报错,会再次触发熔断,又进入熔断时间。
注意:处于半开探测状态时,第一次请求接口也是会正常进入接口执行的,要不然也没有办法判断是否还存在错误。

在这里插入图片描述

与预期一致

热点参数规则

热点参数流控规则是一种更细粒度的流控规则,它允许将规则具体到参数上。它只能对QPS模式进行限制。

用处场景:

​ 1.热点参数虽然会做缓存,但是为了防止缓存击穿的情况,也还是需要对热点数据做限流

​ 2.防止恶意供给,强刷

**注意:**热点规则,必须使用@SentinelResource注解,如果对接口资源 /rule/myInter 这种格式,会不生效

比如,现有一个根据id查询商品的接口,需要对该接口进行每秒10次的QPS限制,并且需要针对 id=1 的QPS设置为 2

id=2的QPS设置为3。

定义资源

    /**
     * 根据id查询商品 - 热点参数限流效果 测试
     */
    @GetMapping("/getById/{id}")
    @SentinelResource(
            value = "getById",
            blockHandlerClass = BlockHandle.class,
            blockHandler = "MyHotBlock")
    public R myError(@PathVariable("id") String id) {
        System.out.println("查询商品:" + id);
        return R.ok("查询商品:" + id);
    }

控制台设置

分为两步,一步设置参数索引位置,以及普通参数的流控规则

在这里插入图片描述

保存后再次编辑,点击高级选项,才会出现热点参数具体的值设置

在这里插入图片描述

测试

普通参数走大局限流,每秒超过10次才限流
热点参数 1 每秒超过2次才限流
热点参数 2 每秒超过3次才限流

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

预期一致

系统规则

Sentinel 系统自适应保护从整体维度对应用入口流量进行控制,结合应用的 Load、总体平均 RT、入口 QPS 和线程数等几个维度的监控指标,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

Sentinel 做系统自适应保护的目的:

  • 保证系统不被拖垮
  • 在系统稳定的前提下,保持系统的吞吐量

在这里插入图片描述

系统规则

在这里插入图片描述

3.规则持久化

控制台不像代码,写入规则就一直生效,控制台新增的规则,是通过api将规则更新到内存中,重启程序即失效。

在这里插入图片描述

生产环境下一般搭配 nacos 使用推模式来进行规则持久化

在这里插入图片描述

引入依赖
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

配置yml ,将程序 连接到 nacos

spring: 
 cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080
      # web-context-unify: false
      datasource:
        flow-rule:
          server-address: 127.0.0.1:8848 #nacos地址
          username: nacos #nacos 账户密码
          password: nacos
          dataId: sentinel-dev # 在nacos中,该配置文件的名称
          rule-type: FLOW # 控制模式为 流控

nacos上面写好控制规则

在这里插入图片描述

然后启动程序,正确连接到nacos之后,就会发现nacos中写好的流控规则,就已经出现在页面上了。

**注意:**控制台上面的修改,不会同步反推更改到nacos上(需要阅读源码来进行反推,日后研究)

参考视频
★,°:.☆( ̄▽ ̄)/$:.°★

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值