飞天班第55节:SpringCloud Aibaba-Sentinel流量卫兵

2020/07/04

上一节已讲了Nacos,笔记整合到了第30节中

1. 认识Sentinel

1.1. Sentinel的介绍

官方文档在Github地址:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel的核心部件:

  • 核心库(Java客户端):不依赖于任何框架,只要有Java环境就可以使用,对Dubbo和SpringCloud等框架有较好的支持,sentinel会在应用启动的时候同时启动一个Http Server,默认端口是8719,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
  • 控制台(Dashboard):控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。基于SpringBoot开发,打包后即可直接运行,不需要额外tomcat支持,就像Nacos也有控制台

1.2. 对比Hystrix

sentinel的功能和hystrix非常相似,但sentinel晚于hystrix出现,所以功能更加全面,使用更便捷,用户请求先被Sentinel拦截,判断规则是否通过

  服务监控方面 灵活配置方面
Hystrix 需要开发人员自己搭建监控平台并通过turbine来收集监控信息 没有一个完整服管理平台给我们提供更细粒度的配置,比如:流控,速率控制,服务熔断,服务降级等,所有的降级熔断的配置都需要提前在yaml里设计好并对接口层面支持较弱,对于业务的突发变更配置不灵活。(修过配置要么重启服务,或者通过spring config和spring bus消息总线来热加载配置)
Sentinel 单独有一个组件独立出来进行监控和业务没有关系 统一的界面化配置,更细粒度的设置以及灵活的处理

2. Sentinel的应用启动

版本地址: https://github.com/alibaba/Sentinel/releases

直接去github上先下载一个控制台dashboard

https://github.com/alibaba/Sentinel/releases/download/1.7.2/sentinel-dashboard-1.7.2.jar
# 默认端口8080
java -jar -Dserver.port=8080 sentinel-dashboard-1.7.2.jar
# 后台启动
nohup java -jar -Dserver.port=8067 sentinel-dashboard-1.7.2.jar > sentinel.log 2>&1 &
# localhost:8080
# 用户名密码都是:sentinel

访问控制台,还没有服务被访问

3. 服务集成Sentinel

1、导入依赖

pom父依赖要导入

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  <version>2.2.1.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

具体module调用里加入sentinel的依赖包

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

2、application.yaml的配置里增加sentinel部分

server:
  port: 30001
spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 #将服务的降级熔断托管到具体的sentinel中

3、测试使用,启动类不用修过,web层接口定义ProviderController类

package com.icodingedu.supermall.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
//配置支持动态更行
@RefreshScope
public class ProviderController {

    @Value("${config.info}")
    private String config;

    @Value("${server.port}")
    private String server_port;

    @GetMapping("sayhello")
    public String getInfo(){
        return "say hello: "+server_port+" config: "+config;
    }

    @GetMapping("testa")
    public String testA(){
        return "this is test A";
    }

    @GetMapping("testb")
    public String testB(){
        return "this is test B";
    }
}

sentinel里的服务是懒加载,只要我们的服务被访问或才会出现在sentinel里,需要注册进sentinel里的controller必须要访问一次才能显示。

注意:访问了哪个接口,哪个接口才会出现在sentinel中

注意:如果把Sentinel控制台部署在云服务器上(外网),你本地应用能连接到Sentinel控制台,但是Sentinel控制台无法拉取你应用的监控信息,这就需要讲一下Sentinel的工作原理:

​ 程序应用引入了Sentinel的jar包后,其实就相当于Sentinel的一个客户端,程序应用启动的时候会在机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做通信交互,默认端口是8719,application.yml配置spring.cloud.sentinel.transport.port: 8719 修改,所以要保证 Sentinel 控制台与 Sentinel客户端的网络是互通的。

看控制台的日志:

在本地启动Sentinel控制台

4. 流控设置

4.1. QPS限流

将服务注册到sentinel中就可以对相应的接口进行流控设置,这里是限制每秒并发最高访问1次,单位是秒

这个流控规则支持动态配置直接生效的,不需要像其他代码层面的流控规则,还需要启动服务,配置修改后直接生效,

如何进行QPS的合理设置?

  • 经过压力测试而来
  • 疲劳测试,按最高并发访问量/2 进行几天的测试,看应用是否都正常

4.2. 线程限流

限制访问的用户线程数

如果我们在阈值类型上讲QPS设置成线程数,单机阈值还是1,这时你点得再快,也不会有限流报错,因为只有你一个用户线程在访问这个接口。

配置完成后快速点击接口服务是不会出现流控提示的,这里线程指的是只有一个线程来处理请求,处理完就处理下一个,如果并发请求过来处理不完就来下一个了才会出现 blocked by sentinel的错误提示。

4.3. 流控的关联模式

相当于别人犯错误,你自己买单,当B接口超过阈值后,对A进行限流

接口/testb的访问是没有限流的,当它的每秒访问超过1次,接口/testa的访问就会被sentinel限流,报blocked by sentinel的提示。

具体应用场景:付款太多的时候,就对退款进行限流。

4.4. Warm up

流控预热

可以去看下官网https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮

默认 coldFactor 为 3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。这个配置相当于接口在5秒的预热内是10/3个访问阈值,超过后就限流报错,5秒后阈值为10个的方式 ,让系统缓慢进入流量压力阶段,提前适应一下系统的压力,不至于流量一来系统就挂掉。

生活中的例子:汽车启动预热

4.5. 限流队列

这个时间就是队列的等待时间,单位是ms,如果超过等待时间前一个任务还没有完成就会报错,Sentinel进行限流。你访问够快了,我让你慢下来等待,降低访问的频次。

5. 熔断降级

目的:让服务快速失败,避免请求发生堆积导致服务雪崩

我们先看一下官网的解释https://github.com/alibaba/Sentinel/wiki/熔断降级

我们通常用以下几种方式来衡量资源是否处于稳定的状态:

  • 平均响应时间 (DEGRADE_GRADE_RT):当 1s 内持续进入 N 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。
  • 异常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量 >= N(可配置),并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
  • 异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

注意:异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。为了统计异常比例或异常数,需要通过 Tracer.trace(ex) 记录业务异常。

5.1. RT降级

平均响应时间降级,我们先构造一个web层接口

@GetMapping("testc")
public String testC(){
  try{
   	TimeUnit.MILLISECONDS.sleep(300);
  }catch (Exception ex){
    ex.printStackTrace();
  }
  return "this is test C";
}

这个配置相当于在1秒内N个请求的平均相应时间超过200ms,那么在下一个10秒内所有的请求全部返回系统的降级提示

5.2. 异常比列降级

1秒内所有请求的错误占比超过20%,那么接下来的10秒内,系统直接进入降级

5.3. 异常数降级

1分钟内所有请求的错误数量超过3个,在下一个10秒内,系统直接进入降级

6. 热点参数限流

同样还是先看官网https://github.com/alibaba/Sentinel/wiki/热点参数限流

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。针对某个数据的访问进行限制,粒度更细

6.1. 基本配置

先写一个web层接口定义ProviderController类

@GetMapping("testhot") //地址作为资源名需要加斜杠/testhot
@SentinelResource(value = "hotkey",blockHandler = "hotkeyFallback") // 指定资源名hotkey
public String testHotKey(@RequestParam(value="p1",required=false) String p1,
                         @RequestParam(value="p2",required=false) String p2){
  return "返回的testhotkey:参数1:"+p1+"  参数2:"+p2;
}

//这个就是自定义的fallback,可以返回json字符串给前端 
public String hotkeyFallback(String p1,String p2,BlockException exception){
  return "这是hotkeyFallback";
}

请求方法里设定参数出现在链接里就会按照上面的规则进行限流,1秒内查过请求阈值1就触发blockhandler,在链接里参数出现的顺序无关只要有就行,参数索引0是我们的方法里参数的顺序,从0开始

6.2. 高级配置

如果出现参数顺序为1的参数就触发每秒单机阈值1的规则,如果值是gavin的就触发每秒为10的阈值

如果出现参数顺序为1的参数就触发每秒单机阈值10的规则,如果值是arry的就触发每秒为1的阈值

这时候有两个规则,都会去判断,满足木桶原则,以最低限制的为准

访问http://localhost:8080/testhot?p1=gavin&p2=arry,就容易触发触发每秒为1的阈值

7. 系统自适应限流规则

官网:https://github.com/alibaba/Sentinel/wiki/系统自适应限流

7.1. 背景

在开始之前,我们先了解一下系统保护的目的:

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

长期以来,系统保护的思路是根据硬指标,即系统的负载 (load1) 来做系统过载保护。当系统负载高于某个阈值,就禁止或者减少流量的进入;当 load 开始好转,则恢复流量的进入。这个思路给我们带来了不可避免的两个问题:

  • load 是一个“结果”,如果根据 load 的情况来调节流量的通过率,那么就始终有延迟性。也就意味着通过率的任何调整,都会过一段时间才能看到效果。当前通过率是使 load 恶化的一个动作,那么也至少要过 1 秒之后才能观测到;同理,如果当前通过率调整是让 load 好转的一个动作,也需要 1 秒之后才能继续调整,这样就浪费了系统的处理能力。所以我们看到的曲线,总是会有抖动。
  • 恢复慢。想象一下这样的一个场景(真实),出现了这样一个问题,下游应用不可靠,导致应用 RT 很高,从而 load 到了一个很高的点。过了一段时间之后下游应用恢复了,应用 RT 也相应减少。这个时候,其实应该大幅度增大流量的通过率;但是由于这个时候 load 仍然很高,通过率的恢复仍然不高。

TCP BBR 的思想给了我们一个很大的启发。我们应该根据系统能够处理的请求,和允许进来的请求,来做平衡,而不是根据一个间接的指标(系统 load)来做限流。最终我们追求的目标是 在系统不被拖垮的情况下,提高系统的吞吐率,而不是 load 一定要到低于某个阈值。如果我们还是按照固有的思维,超过特定的 load 就禁止流量进入,系统 load 恢复就放开流量,这样做的结果是无论我们怎么调参数,调比例,都是按照果来调节因,都无法取得良好的效果。

Sentinel 在系统自适应保护的做法是,用 load1 作为启动自适应保护的因子,而允许通过的流量由处理请求的能力,即请求的响应时间以及当前系统正在处理的请求速率来决定。

7.2. 系统规则

系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。

系统规则支持以下的模式:

  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

8. @SentinelResource

目的:统一处理限流异常

使用@SentinelResouce注解可以指定资源的信息访问,并设置本地限流的访问返回方法,如果不设置就会返回系统的限流提示,如果不使用自定义的限流提示会有几个问题

  • 系统默认的返回提示不能体现业务需求
  • 自定的限流异常处理逻辑和业务代码耦合在一起对业务不能很好的管理
  • 每个业务都有自己的异常处理,代码会膨胀
  • 全局统一的处理没有体现

8.1. 自定义blockhandler

服务限流,限流异常统一处理类SentinelBlockHandler.java

package com.jude.customer.handler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.jude.common.constants.ResultCodeEnum;
import com.jude.common.vo.R;
import org.springframework.stereotype.Service;

@Service
public class SentinelBlockHandler {

	public static R hotkeyBlock(String p1, String p2, BlockException exception){
		return R.setResult(ResultCodeEnum.SENTINEL_HOTKEY_BLOCK_ERROR).data("参数p1",p1).data("参数p2",p2);
	}

  // 注意一定要是static 并且 带BlockException ex 参数
	public static String  serviceABlock(int req,BlockException ex){
		return "service A sentinel block limit";
	}
}

fallback都统一放到处理类FallbackHandler.java

@Service
public class FallbackHandler {
	public static R serviceAFallback(int req){
		return R.error().message("service A fallback").data("req",req);
	}
}

web层接口的定义ProviderController.java,指定限流异常处理类和具体的方法

@GetMapping(value = "testa",produces="application/json;charset=UTF-8")
@SentinelResource(value="serviceA"
                  ,blockHandlerClass = SentinelBlockHandler.class,blockHandler = "serviceABlock"
                  ,fallbackClass = FallbackHandler.class,fallback = "serviceAFallback")
public R testA(@RequestParam(value="req",required = false,defaultValue = "0") int req){
  if(req == 1){
    int i = req/0;
  }
  return R.ok().message("this is test A");
}

限流规则

测试

1、都配置blockHandler 和 fallback ,触发限流降级规则走的是blockHandler方法

方法出现异常,走的是fallback方法

2、只配置了fallback没有配置blockHandler,触发限流降级规则而抛出BlockException也会进入fallback方法

3、都没有配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出。

fallback与blockHandler的区别

  • fallback是针对方法出现异常了,则会进入fallback方法。
  • blockhandler是针对流控设置,超出规则,则会进入blockhandler方法。

8.2. 自定义fallback

服务降级,在controller方法里实现

@GetMapping("testa")
@SentinelResource(value = "serviceA",fallback = "serviceFial")
public String testA(@RequestParam(value="req",required = false,defaultValue = "0") int req){
  if(req==1){
    int i=1/0;
  }
  return "this is test A";
}
//上面方法的fallback
public String serviceFial(int req){
  return "servcie A fallback : "+req;
}

8.3. fallback异常忽略

//这里指定异常忽略后,该异常不会再走本地存根
@GetMapping("testa")
@SentinelResource(value = "serviceA",fallback = "serviceFial",exceptionsToIgnore = {ArithmeticException.class})
public String testA(Integer req){
  if(req==1){
    int i=1/0;
  }
  return "this is test A";
}

9. Sentinel和Feign的集成

参考之前写的博客 :/springcloud/2019/12/18/springcloud-sentinel.html

服务imall-customer通过feignclient调用服务imall-search,两个服务都注册到Nacos,通过Sentinel 限流imall-customer的feign请求,当触发限流规则会走fallback方法

1、pom.xml导入依赖,版本在父依赖项目中统一管理,Nacos做服务注册中心,配置中心,Sentinel做流量卫兵

父依赖项目pom.xml要导入

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  <version>2.2.1.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

imall-customer的pom.xml里加入nacos、sentinel、feign的依赖包

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2、imall-customer的appliction.yaml中要开启feign的关联开关 feign.sentinel.enabled=true

spring:
  application:
    name: imall-customer
  cloud:
    nacos:
      discovery:
        server-addr: 139.199.13.139:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8067 #将服务的降级熔断托管到具体的sentinel中
        port: 8719
server:
  port: 20004
feign:
  sentinel:
    enabled: true
management:
  endpoints:
    web:
      exposure:
        incloud: '*'

3、FeignClient接口SearchClient.java

@FeignClient(name="imall-search",fallback = SearchClientHystrixFallback.class)
public interface SearchClient {
	@GetMapping("/search/test")
	String test();
}

fallback实现类SearchClientHystrixFallback.java

@Component
public class SearchClientHystrixFallback implements SearchClient {
	@Override
	public String test() {
		return "服务降级,调用imall-search 本地快速失败";
	}
}

4、web层接口的定义ProviderController.java

@RestController
public class ProviderController {
	@Autowired
	SearchClient searchClient;
  
  @GetMapping("/search-feign")
	public String searchFeign(){
		return searchClient.test();
	}
}

5、启动Nacos,Sentinel控制台,工程imall-customer,imall-search,测试

正常访问http://localhost:20004/search-feign

登录Sentinel控制台,发现会生成两个资源名

对GET:http://imall-search/search/test 进行流控

当快速访问http://localhost:20004/search-feign,触发流控规则(每秒最多访问1次),会走fallback方法

10. Sentinel规则的持久化

当注册到sentinel的服务一旦重启,所有的规则都将失效,这个时候就需要将规则持久化

可以结合Nacos将配置进行持久化,当然也可以持久化到数据库或Redis中

配置持久化

上面的imall-customer工程使用了Sentinel进行限流,需要它持久化自己的限流规则

1、在项目的pom.xml添加依赖

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

2、imall-customer要从Nacos读取配置,所以使用的是boostrap.yml配置文件,不是application.yml

server:
  port: 30001
spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 #将服务托管到具体的sentinel中
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848 # 如果nacos做了集群化,使用nginx进行复杂均衡,把所有nacos集群的地址都写上
            dataId: imall-customer-service # 限流规则在nacos的配置文件dataId
            namespace: 7b780017-11a0-4bd0-bcae-ad75e0dbf02e # 命名空间,默认public
            groupId: DEFAULT_GROUP # 分组
            data-type: json
            rule-type: flow

通过配置文件点击源码找到的是SentinelProperties.class类

点击DataSourcePropertiesConfiguration.class,发现支持持久化的配置中心有:nacos、zookeeper、apollo、redis、consul

3、登录Nacos创建dataId为imall-customer-service 的json配置文件,要记得发布哦,内容如下:

对上面的web层接口 /search-feign进行限流,你也可以在方法上添加注解@SertinelResource给它一个资源名

[
    {
        "resource": "/search-feign",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

# resource:资源名称
# limitApp:来源应用
# grade:阈值类型,0-线程数,1-QPS
# count:单机阈值
# strategy:流控模式,0-快速失败,1-Warm,2-排队等待
# clusterMode:是否集群

正常访问http://localhost:20004/search-feign

其实限流规则已经在nacos配置,就是QPS的阀值是1,当我快速访问http://localhost:20004/search-feign,触发流控提示

登录Sentinel控制台,发现/search-feign的流控规则,它是从Nacos配置中心读取过来的

注意这的流控资源名是/search-feign,不是GET:http://imall-search/search/test ,所以当触发流控规则时,并没有走Feignclient接口的fallback方法进行服务降级,因为它们是不同的资源名。

测试Sentinel控制台是否会推送修改后的规则到Sentinel 核心库 java客户端

尝试修改/search-feign的流控规则,把QPS阀值改为10

当我快速访问http://localhost:20004/search-feign,并没有报被限流了,都可以正常访问,说明Sentinel控制台推送了新的规则给

imall-cutomer的HttpServer,注册了新的规则。再看看Nacos配置中心的imall-customer-service 配置文件发现并没有修改,当我们重启项目imall-cutomer,它会重新从Nacos配置中心读取default规则,Sentinel控制台也一样从Nacos配置中心读取default规则

总结:

  • Sentinel规则持久化到Nacos后,启动项目应用会从Nacos读取流控规则,可以称为default规则;

  • Sentinel 控制台可以修改流控规则推送给项目应用(Java客户端),并按新规则生效,但不能修改default规则,所以重启应后还是会按default规则进行流控。
  • 我们可以定期从Nacos上修改default规则。
  • Sentinel控制台一样是懒加载簇点链路,流控规则的,就是你不访问,我不显示。

Post Directory