zoukankan      html  css  js  c++  java
  • SpringCloud Sentinel 学习笔记

    Sentinel 教程学习笔记

    1. Sentinel 介绍

    1.1 Sentinel 的组成

    核心库(Java 客户端): 不依赖任何框架 / 库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持;

    控制台(Dashboard): 基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器;

    1.2. Sentinel 的特征

    丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷(对于突然到来的大量请求,您可以配置流控规则,以稳定的速度逐步处理这些请求,从而避免流量突刺造成系统负载过高)、集群流量控制、实时熔断下游不可用应用等;

    完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况;

    广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel;

    完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等;

    1.3. 相关概念

    资源 资源是Sentinel的关键概念,它可以是Java应用程序中的任何内容,比如程序提供的服务,或者是一段代码。只要通过Sentinel API定义的代码,就是资源,能够被Sentinel保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来表示资源。

    规则 规则是指围绕着资源的实时状态设定的规则,它可以包括流量控制规则、熔断降级规则以及保护规则。所有规则可以动态实时调整。

    流量控制:根据系统的处理能力对流量进行控制,处理不了的请求直接丢弃;

    熔断降级:如果某个资源不稳定,最终会导致请求发生堆积,在微服务系统中进而导致级联错误,熔断机制可以应对这种问题,对资源进行控制,让请求快速失败,避免影响其他的资源而产生级联故障;当资源被降级后,在接下来的降级时间窗口内,对该资源的调用都会自动熔断(默认行为是抛出DegradeException);

    2. Sentinel 初体验

    使用SpringBoot工程,通过Sentinel的API来体验一把资源的限流保护;下面的代码是通过在代码中定义限流规则的,在介绍到Sentinel控制台后,我们就可以在控制里动态的设置限流规则;

    2.1 限流规则体验

    2.1.1 修改pom.xml添加依赖

    <!--添加Sentinel依赖-->
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-core</artifactId>
                <version>1.7.2</version>
            </dependency>
    

    2.1.2 定义一个Controle来测试CentinelAPI

    关键点

    • SphU.entry 来定义限流入口,并定义资源名称;
    • 使用@PostConstruct注解在构造方法执行后,添加自定义的限流规则;
    • BlockException 限流规则被触发后抛出的异常;
    package com.linwei.sentinel.control;
    
    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 org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.PostConstruct;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author: linwei
     * @date: 2021/7/15 22:41
     * @Description:
     */
    
    @RestController
    public class TestContorl {
    
        @GetMapping("/hello")
        public String hello(){
            try (Entry entry = SphU.entry("Hello")){ //限流入口
                return "Hello Sentinel!";  //这里就是被保护的资源
            }catch (BlockException ex){
                ex.printStackTrace();
                return "系统繁忙,稍后重试!";  //限流规则触发后的操作
            }
    
        }
    
        // 定义限流规则
        // @PostConstruct 该注解的作用是在当前类的构造原函数执行之后执行的方法
        @PostConstruct
        public void initFlowRules(){
            //1. 创建存放限流规则的集合
            List<FlowRule> rules = new ArrayList<>();
            //2. 创建限流规则
            FlowRule rule1 = new FlowRule();
            // 定义资源
            rule1.setResource("Hello");
            // 定义限流规则类型
            rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
            // 设置QPS的限流值
            rule1.setCount(2);
    
            //3. 将限流规则存放到集合中
            rules.add(rule1);
            //4. 加载限流规则
            FlowRuleManager.loadRules(rules);
    
        }
    }
    
    

    2.1.3 测试限流效果

    我们在代码里设置的限流规则是每秒处理两个QPS,因此当我们在浏览器频繁刷新请求/hello 时,就会触发限流规则;

    浏览器显示如下:

    Hello Sentinel!
    
    系统繁忙,稍后重试!
    

    2.2 熔断降级体验

    熔断降级会在调用链路中,某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源导致级联错误。当资源被降级后,在接下来的降级时间窗口内,对该资源的调用都会自动熔断(默认行为是抛出DegradeException);

    熔断降级的规则设置有两种方式:

    • 本地代码设置;
    • 在Sentinel控制台动态设置;

    以下以本地代码为例进行演示:

    2.2.1 添加依赖;

    这一步跟上面的2.1.1是一样的,已经添加过依赖,这一步就可以跳过;

    2.2.2 在controller中定义资源

    下面是使用了注解的方式定义资源;

    @RestController
    public class TestController {
    
        // Sentinel 注解方式定义资源;  限流控制
        @GetMapping("ann-test")
        @SentinelResource(value="sentinel-ann",blockHandler = "exceptionHandler")
        public String annotionTest(){
            return "hello sentinel annotation";
        }
    
        // blockHandler函数
        public String exceptionHandler(BlockException ex){
            ex.printStackTrace();
            return "系统繁忙,请稍后";
        }
    
    
        // Sentinel 注解方式定义资源  熔断控制
        @SentinelResource(value = "sentinel-deg",fallback = "exceptionHandler2")
        @RequestMapping("/deg-test")
        public String degradeTest(){
            return "hello sentinel degrade test!";
        }
    
        //降级方法
        public String exceptionHandler2(){
            return "触发熔断降级,系统繁忙,请稍后";
        }
    
    }
    

    2.2.3 在controller定义熔断规则

    我们继续在上面的代码里,用代码的方式进行定义熔断规则,使用sentinel控制台后,这个步骤就不用要了,只需要上面定义好资源后,在控制台去定义规则即可;

        // 定义熔断规则
        // @PostConstruct 该注解的作用是在当前类的构造原函数执行之后执行的方法
        @PostConstruct
        public void initFlowRules(){
            //1. 创建存放限流规则的集合
            List<DegradeRule> rules = new ArrayList<>();
            //2. 创建限流规则
            DegradeRule rule = new DegradeRule();
            // 定义资源
            rule.setResource("sentinel-deg");
            // 定义限流规则类型:熔断降级(秒级RT)类型
            rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
            // 设置阈值
            rule.setCount(0.01);
            // 降级的时间窗口,单位为s
    		rule.setTimeWindow(10);
            //3. 将限流规则存放到集合中
            rules.add(rule);
            //4. 加载限流规则
            DegradeRuleManager.loadRules(rules);
    
        }
    

    在浏览器方式http://localhost:8080/deg-test,慢速刷新可以正常返回,快速刷新几次后,出现触发熔断降级,系统繁忙,请稍后 ,并且之后再次刷新,即使慢速刷新还是提示繁忙,等待10秒后,又正常显示了,说明对资源的熔断降级生效了。

    3. Sentinel 控制台

    3.1 本地控制台搭建

    1. 下载jar包;
    • 方式1:从 release 页面 下载最新版本的控制台 jar 包(sentinel-dashboard-1.8.2.jar);
    • 方式2:也可以从最新版本的源码自行构建 Sentinel 控制台;
    1. 启动jar包
    java -Dserver.port=9000 -jar sentinel-dashboard-1.8.2.jar
    
    1. 访问Sentinel控制台

    浏览器打开: http://localhost:9000/ 登陆账号密码默认均为sentinel;

    3.2 客户端接入控制台

    (参考官网,普通Springboot项目接入Sentinel控制台)
    默认情况下Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包。也可以配置
    sentinel.eager=true ,取消Sentinel控制台懒加载。
    打开浏览器即可展示Sentinel的管理控制台。

    1. 在客户端pom.xml引入 Transport 模块来与 Sentinel 控制台进行通信
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-transport-simple-http</artifactId>
        <version>1.8.2</version>
    </dependency>
    
    1. 启动时加入 JVM 参数指定sentinel控制台的Ip和端口,并指定当前客户端的名称
    -Dcsp.sentinel.dashboard.server=localhost:9000 -Dproject.name=sentinel-demo
    

    完成以上步骤后即可在 Sentinel 控制台上看到对应的应用,机器列表页面可以看到对应的机器,如果看不到,就访问以下客户端,因为sentinel默认是懒加载;

    1. 将代码里的限流规则注释掉,在sentinel控制台添加限流规则
    @RestController
    public class TestContorl {
    
        @GetMapping("/hello")
        public String hello(){
            Entry entry = null;
            try { //限流入口
                entry = SphU.entry("Hello");
                return "Hello Sentinel!";  //这里就是被保护的资源
            }catch (BlockException ex){
                ex.printStackTrace();
                return "系统繁忙,稍后重试!";  //限流规则触发后的操作
            } finally {
                if (entry != null) {
                    entry.exit();
                }
    
                ContextUtil.exit();
            }
        }
    
        // 定义限流规则
        // @PostConstruct 该注解的作用是在当前类的构造原函数执行之后执行的方法
        /*@PostConstruct
        public void initFlowRules(){
            //1. 创建存放限流规则的集合
            List<FlowRule> rules = new ArrayList<>();
            //2. 创建限流规则
            FlowRule rule1 = new FlowRule();
            // 定义资源
            rule1.setResource("Hello");
            // 定义限流规则类型
            rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
            // 设置QPS的限流值
            rule1.setCount(2);
    
            //3. 将限流规则存放到集合中
            rules.add(rule1);
            //4. 加载限流规则
            FlowRuleManager.loadRules(rules);
    
        }*/
        
    }
    

    image
    image

    3.3 Sentinel 定义资源的方式

    Sentinel 定义资源的方式有以下几种:

    • 抛出异常的方式
    • 返回布尔值方式
    • 异步调用支持
    • 注解方式
    • 主流框架的默认适配

    3.3.1 抛出异常的方式

    Sentinel中SphU包含了try-catch风格的API,用这种方式,当资源发生了限流之后会抛出BlockException异常。这个时候可以捕获异常,进行限流之后的逻辑处理,例如:
    把需要控制流量的代码用 Sentinel API SphU.entry("HelloWorld") 和 entry.exit() 包围起来即可

    try (Entry entry = SphU.entry("Hello")){ //限流入口,被保护的资源
            return "Hello Sentinel!";  //这里就是被保护的资源
        }catch (BlockException ex){
            ex.printStackTrace();
             return "系统繁忙,稍后重试!";  //限流规则触发后的操作
        } 
    

    3.3.2 返回布尔值方式定义资源

    Sentinel中SphO的API提供if-else风格的API,用这种方式,当资源发生了限流之后会返回false,这个时候可以根据返回值,进行限流之后的逻辑处理;

    SphO.entry(xxx)需要与SphO.exit()成对出现,否则会导致调用链记录异常,抛出ErrorEntryFreeException异常

    定义一个测试的controller,然后在Sentinel控制添加对应资源的限流规则,查看限流时候生效;正常情况下,限流触发后会执行else里面的逻辑;

    @RequestMapping("boolean-test")
        public String booleanTest(){
            if(SphO.entry("sentinel-boolean")){ //限流入口,被保护的资源名称
                try {
                    // 被保护的资源...
                    return "访问成功!";
                }finally {
                    // SphO.entry(xxx)需要与SphO.exit()成对出现,否则会导致调用链记录异常,抛出ErrorEntryFreeException异常
                    SphO.exit(); //限流出口
                }
            }else{
                // 限流规则被触发后的逻辑处理
                return "限流规则触发,访问失败!";
            }
        }
    

    3.3.3 异步调用支持

    Sentinel支持异步调用链路,在异步调用中,需要通过SphU.asyncEntry(XXX)定义资源,并需要在异步回调函数中调用exit方法;

    1. 在本地引用的引导类中添加注解@EnableAsync, 表示springboot项目开启异步调用支持;
    @EnableAsync
    @SpringBootApplication
    public class SentinelDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SentinelDemoApplication.class, args);
        }
    
    }
    
    1. 创建SyncService编写异步调用方法
    @Service
    public class MyAsyncService {
    
        // @Async 注解表示该方法为异步调用方法
        @Async
        public void hello(){
            System.out.println("--->异步方法开始");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("--->异步方法结束");
        }
    }
    
    1. 在controller中调用异步方法,实现异步调用限流控制
        // Sentinel 对异步调用的支持
        @Autowired
        private MyAsyncService asyncService;
        @GetMapping("async")
        public void asyncTest(){
            // 1. 进行限流控制
            AsyncEntry asyncEntry = null;
            try {
                asyncEntry = SphU.asyncEntry("sentinel-async"); // 定义限流资源名称(限流入口)
                asyncService.hello(); // 异步方法调用
                System.out.println("----continue..."); // 异步方法调用后该语句继续执行
            } catch (BlockException e) {
                System.out.println("---> 系统忙,请稍后!");  // 被限流或降级触发后的逻辑处理
            }finally {
                if(asyncEntry != null){
                    asyncEntry.exit();  // 限流出口
                }
            }
    
        }
    

    3.3.4 注解方式定义资源

    Sentinel支持通过注解 @SentinelResource 注解方式定义资源并配置 blockHandler 函数来进行限流之后的处理。
    步骤:

    1. 引入相关依赖;
      因为Sentinel中使用AspectJ的扩展用于自定义资源、处理BlockException等,所以需要在项目中引入sentinel-annotation-aspectj依赖;
        <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-annotation-aspectj</artifactId>
                <version>1.8.2</version>
        </dependency>
    
    1. 创建AspectJ的配置类
    @Configuration
    public class SentinelAspectConfig {
        
        @Bean
        public SentinelResourceAspect sentinelResourceAspect(){
            return new SentinelResourceAspect();
        }
    }
    
    1. 创建testController,进行测试验证;
       // Sentinel 注解方式定义资源
        @GetMapping("ann-test")
        @SentinelResource(value="sentinel-ann",blockHandler = "exceptionHandler")
        public String annationTest(){
            return "hello sentinel annotation";
        }
    
        // blockHandler函数
        public String exceptionHandler(BlockException ex){
            ex.printStackTrace();
            return "系统繁忙,请稍后";
        }
    

    4. Sentinel高级

    4.1 Sentinel 和 SpringCloud整合

    SrpingCloudAlibaba 是阿里巴巴提供,致力于提供微服务开发的一站式解决方案。Spring Cloud Alibaba 默认为Sentinel 整合了Servlet、RestTemplate、FeignClient和Spring WebFlux。 Sentinel在Spring Cloud生态中,不仅不全了Hystrix在Servlet和RestTemplate这一块的空白,而且还兼容了Hystrix在FeignClent中限流降级的用法,并且支持运行时灵活配置和调整连休降级规则;

    具体步骤

    1. 创建SpringBoot项目,在项目中引入spring-cloud-starter-alibaba-sentinel依赖
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-sentinel</artifactId>
                <version>2.1.0.RELEASE</version>
            </dependency>
    
    1. 创建Controller用来测试
    @RestController
    public class TestController {
    
        // Sentinel 注解方式定义资源
        @GetMapping("ann-tet")
        @SentinelResource(value="sentinel-ann",blockHandler = "exceptionHandler")
        public String annotionTest(){
            return "hello sentinel annotation";
        }
    
        // blockHandler函数
        public String exceptionHandler(BlockException ex){
            ex.printStackTrace();
            return "系统繁忙,请稍后";
        }
    
    }
    
    1. application.properties配置文件中添加Sentinel控制台配置
    # 应用名称
    spring.application.name=springcloudsentinel-demo
    # 应用服务 WEB 访问端口
    server.port=8081
    # 设置Sentinel控制台的主机地址和端口
    spring.cloud.sentinel.transport.dashboard=localhost:9000
    

    4.2 Sentinel对Fegin的支持

    Sentinel适配了Feign组件。如果想要使用,除了引用spring-cloud-starter-alibaba-sentinel的依赖,还需要两个步骤:

    • 配置打开Sentinel对Feign的支持:feign.sentinel.enable=true
    • 加入spring-cloud-starter-openfeign依赖使Sentinel starter自动化配置类生效
    1. 引入Spring Cloud Alibaba Sentinel依赖

             <dependency>
                  <groupId>com.alibaba.cloud</groupId>
                  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
              </dependency>
      
      
    2. 在application.properties配置文件中开启Sentinel对Feign的支持

      #设置Sentinel控制台的主机地址和端口
      spring.cloud.sentinel.transport.dashboard=localhost:9000
      #打开Sentinel对Feign的支持
      feign.sentinel.enabled=true
      
    3. 创建FallbackService,作为限流降级回调类,并在FeignAgent进行流控降级回调配置

      // 限流或降级的回调类
      @Component
      public class FallbackService implements FeignAgent {
          //限流和降级的处理
          @Override
          public String hello() {
              return "系统繁忙,请稍候";
          }
      }
      
      

    定义feign客户端接口

    // feign 客户端
    @FeignClient(value = "sentinel-feign-provider", fallback = FallbackService.class)
    public interface FeignAgent {
    
        @GetMapping("/api/v1/hello")
        String hello();
    }
    
    

    服务消费者的测试controller

    @RestController
    public class TestController{
    	@Autowired
    	private FeignAgent feignAgent;
    	
    	@GetMapping("/hello")
    	public String hello(){
    		return feignAgent.hello();
    	}
    }
    
    1. 设置限流规则测试

      Sentinel与Feign整合时,流控规则的编写形式为:http请求方式:协议://服务名/请求路径和参数(请求路径和参数为@FeignClient中的请求路径,也就是本服务调用下游服务的URL)

      例如:GET:http://sentinel-feign-provider/api/v1/hello

      如果快速刷新http://localhost:8090/api/v1/consumer/hello,会出现系统繁忙,请稍候

    2. 请求地址中包含参数的资源名配置

      如果是多个@RequestParam,资源名不需要带上@RequestParam, 如果请求路径中包含@PathVariable,案例如下:

      sentinel控制台资源名定义为:GET:http://sentinel-feign-provider/api/v1/hello/{hello}

      @FeignClient(value = "sentinel-feign-provider", fallback = FallbackService.class)
      public interface FeignAgent {
      
          @GetMapping("/api/v1/hello/{hello}")
          String hello(@PathVariable(value = "hello") String hello);
      }
      

    4.3 Sentinel 对 Spring Cloud Gateway 的支持

    Sentinel整合Spring Cloud gateway

    1. 在gateway的pom.xml中引入依赖;

             <!-- Spring Cloud Alibaba Sentinel 依赖 -->
      		<dependency>
                  <groupId>com.alibaba.cloud</groupId>
                  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
                  <version>2.2.3.RELEASE</version>
              </dependency>
             <!-- Sentinel支持Spring Cloud Gateway 的依赖 -->
      		<dependency>
                  <groupId>com.alibaba.cloud</groupId>
                  <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
                  <version>2.2.3.RELEASE</version>
              </dependency>
      
    2. 创建GatewayConfiguration配置类,配置流控降级回调操作;

      @Component
      public class GatewayConfiguration {
           @PostConstruct
          public void doInit(){
               //设置限流或降级的回调函数
               GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
                   @Override
                   public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, java.lang.Throwable throwable) {
                      return ServerResponse.status(200).syncBody("系统繁忙请稍后");
                   }
               });
           }
      }
      
      
    3. application.yaml中配置sentinel控制台访问地址;

      spring:
        cloud:
          sentinel:
            transport:
              port: 8718
              dashboard: 127.0.0.1:8080
      
    4. 运行测试;

    sentinel在适配spring cloud gateway时提供了两种配置规则:

    • route维度:即在spring配置文件配置的路由条数,资源名为对应的routeId;
    • 自定义API维度:用户可以利用Sentinel提供的API来自定义一些自定义分组;

    在sentinel控制台中,添加网关限流规则的界面跟普通限流规则的界面不太相同,如下图:

    API类型选择Route ID , 就是输入gateway中路径的routeid; 如果选择的是API分组,就需要先在Sentinel控制台网关目录下的菜单“API管理” 里定义API分组,然后在添加留空规则的这个界面上选择API分组;

    image

    4.4 系统自适应保护

    Sentinel系统自适应限流是从应用的整体维度进行入口流量控制,结合应用的Load,CPU使用率,总体平均RT,入口QPS和并发线程数等几个维度的监控指标,通过自适应的流控策略,来让系统入口流量和系统的负载达到一个平衡,让系统尽可能保持最大吞吐量的同时保证系统整体的稳定性;

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

    同样,系统自适应保护规则设置也有两种方式:

    • 本地代码方式;
    • Sentinel控制台动态配置;
    @RestController
    public class SysController {
    
        // 这里定义的资源就没有定义资源的名称和处理函数了,因为系统自适应的维度是整个应用,sentinel也会有默认的限流和降级的处理函数;
        // EntryType.IN 表示这是一个入口资源,自适应保护也只对这样的入口资源生效;
        @SentinelResource(entryType = EntryType.IN)
        @RequestMapping("/sys")
        public String sysHello(){
            return "hello sentinel!";
        }
    
        // 代码方式定义规则
        @PostConstruct
        private void initSystemRule(){
            //1. 创建存放限流规则的集合
            List<SystemRule> rules = new ArrayList<>();
            //2. 创建自适应规则
            SystemRule rule = new SystemRule();
            // 设置入口QPS
            rule.setQps(2);
            //3. 将限流规则存放到集合中
            rules.add(rule);
            //4. 加载限流规则
            SystemRuleManager.loadRules(rules);
        }
    
    }
    

    上面是通过本地代码的方式来定义了限流规则,在Sentinel控制台中添加系统自适应的限流规则的菜单路径是[应用名]-系统规则-新增系统规则


    (以下内容没看太明白--!)

    4.5 Sentinel授权控制

    如果需要根据调用来源来判断该次请求是否运行放行,这个时候可以使用Sentinel的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(Origin)判断资源访问时候通过。

    若配置白名单,则只有来源于白名单的请求才可通行;如果配置的是黑名单,则黑名单内的请求来源将被拒绝,其他请求放行;

    重要属性

    来源访问规则(AuthorintyRule),主要有以下配置项:

    • resource: 资源名,即限流规则的作用对象。
    • limitApp: 请求来源,对应的黑白名单,多个用“,”分隔,如:appA,appB 。
    • strategy: 限制模式,AUTHORITY_WHITE 为白名单模式; AUTHORITY_BLACK 为黑名单模式,默认为白名单模式。

    实现方式

    • 本地代码方式;
    • Sentinel控制台动态配置方式;

    4.5.1 本地代码方式

    添加测试controller,并在代码中定义白名单规则

    @RestController
    public class AuthorintyTestControl {
    
        // 定义资源名以及限流回调方法
        @SentinelResource(value = "white_rule",blockHandler = "exceptionHandler")
        @GetMapping("/white-test")
        public String whiteListTest(){
            return "AuthorintyTestControl";
        }
    
        // 资源被限流/降级时调用
        public String exceptionHandler(BlockException ex){
                return "系统繁忙,请稍后。";
        }
    
    
        // 代码方式定义白名单规则
        @PostConstruct
        private static void initWhiteRules(){
            //1. 创建存放限流规则的集合
            List<AuthorityRule> rules = new ArrayList<>();
            //2. 创建自适应规则
            AuthorityRule rule = new AuthorityRule();
            // 设置授权模式为 白名单模式
            rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
            // 设置白名单
            rule.setLimitApp("192.168.0.104");
            //3. 将限流规则存放到集合中
            rules.add(rule);
            //4. 加载限流规则
            AuthorityRuleManager.loadRules(rules);
        }
    }
    

    添加配置类,设置请求来源解析

    import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
    import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @author: linwei
     * @date: 2021/9/2 22:29
     * @Description:  创建配置类,设置请求来源解析
     */
    
    @Component
    public class SentinelConfig {
    
        @PostConstruct
        public void init(){
            // 获取请求来源的ip地址
            WebCallbackManager.setRequestOriginParser(new RequestOriginParser() {
                @Override
                public String parseOrigin(HttpServletRequest httpServletRequest) {
                    return httpServletRequest.getRemoteAddr();
                }
            });
        }
    }
    

    4.5.2 Sentinel控制台配置方式

    使用控制台配置时,把上面controller中代码里定义的规则注释掉,避免引起混乱,然后在sentinel控制台菜单“授权规则”中添加新的授权规则;

    然后在浏览器进行测试即可;

    4.6 Sentine动态规则

    前面不管是通过Java代码还是通过Sentinel控制台去设置限流规则,都属于手动方式,不够灵活。这种方式一般用于测试和演示,生产环境上一般通过动态设置规则的方式来管理限流规则。也就是说,很多时候限流规则会被存储在文件、数据库或配置中心。Sentinel的DataSource接口给我们提供了对接任意配置源的能力。

    (课程中使用的是Zookeeper作为配置中心,不过现在可能最多的是使用Nacos做为配置中心。之所以使用配置中心,也是为了应用重启后,规则丢失的问题。)

    边系鞋带边思考人生.
  • 相关阅读:
    Redis
    cz_health_day13项目实战
    cz_health_day11
    cz_health_day10
    cz_health_day09
    cz_health_day08
    MySQL8管理系列之二:从5.5升级到8的问题处理
    MySQL8管理系列之一:Mysql 8.0以后版本的安装
    MySQL 5.5.x 数据库导入到 8.0.x 服务器
    修改Mysql 8.0版本的默认数据库目录
  • 原文地址:https://www.cnblogs.com/crazytrip/p/15212602.html
Copyright © 2011-2022 走看看