微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」

文章目录

    • SpringCloud Alibaba Sentinel实现熔断与限流
      • 1、Sentinel
      • 2、安装Sentinel控制台
      • 3、初始化演示工程
      • 4、流控规则
      • 5、降级规则
      • 6、热点key限流
        • 1、基本介绍
        • 2、参数例外项
      • 7、系统规则
      • 8、@SentinelResource
        • 1、按资源名称限流+后续处理
        • 2、按照Url地址限流+后续处理
        • 3、客户自定义限流处理逻辑
        • 4、更多注解属性说明
      • 9、服务熔断功能
        • Ribbon系列
        • Feign系列
        • 熔断框架比较
      • 10、规则持久化

SpringCloud Alibaba Sentinel实现熔断与限流

1、Sentinel

官网

  • 为什么

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第1张图片

一句话解释,之间我们讲解过的Hystrix

  • 能干嘛

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第2张图片

文档地址

  • 怎么玩:解决那些问题

    服务血崩

    服务降级

    服务熔断

    服务限流

2、安装Sentinel控制台

  • sentinel组件有两部分构成:前台和后台8080

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第3张图片

  • 下载jar包并启动

  • 访问页面
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第4张图片

3、初始化演示工程

  • 启动8848成功

  • 建Module

    1、cloudalibaba-sentinel-service8401

    2、POM

      <dependencies>
            <dependency>
                <groupId>com.atguigu.springcloudgroupId>
                <artifactId>cloud-api-commonartifactId>
                <version>${project.version}version>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cspgroupId>
                <artifactId>sentinel-datasource-nacosartifactId>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
            dependency>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-openfeignartifactId>
            dependency>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-actuatorartifactId>
            dependency>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-devtoolsartifactId>
                <scope>runtimescope>
                <optional>trueoptional>
            dependency>
            <dependency>
                <groupId>cn.hutoolgroupId>
                <artifactId>hutool-allartifactId>
                <version>4.6.3version>
            dependency>
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <optional>trueoptional>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
            dependency>
        dependencies>
    

    3、yml

    server:
      port: 8401
    
    spring:
      application:
        name: cloudalibaba-sentinel-service
      cloud:
        nacos:
          discovery:
            server-addr: 192.168.149.102:1111 #Nacos服务注册中心地址
        sentinel:
          transport:
            dashboard: localhost:8080 #配置Sentinel dashboard地址
            port: 8719
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
    

    4、主启动类

    @EnableDiscoveryClient
    @SpringBootApplication
    public class MainApp8401
    {
        public static void main(String[] args) {
            SpringApplication.run(MainApp8401.class, args);
        }
    }
    

    5、业务类FlowLimitController类

    @Slf4j
    public class FlowLimitController
    {
        @GetMapping("/testA")
        public String testA()
        {
            return "------testA";
        }
    
        @GetMapping("/testB")
        public String testB()
        {
            log.info(Thread.currentThread().getName()+"\t"+"...testB");
            return "------testB";
        }
    }
    
  • 启动sentinel8080

  • 启动微服务8401

  • 启动8401微服务后查看sentinel控制台

    1、sentinel采用的是懒加载说明

    http://localhost:8401/testA

    http://localhost:8401/testB

    2、效果
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第5张图片

4、流控规则

  • 基本介绍
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第6张图片
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第7张图片
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第8张图片

  • 流控模式

    1、默认直接

    ​ 直接–>快速失败

    ​ 配置说明

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第9张图片

测试

1秒钟点击1下,OK

点击超过每秒的访问量,进行流量控制

在这里插入图片描述

2、关联

  • 是什么?

    当关联的资源达到阈值时,就限流自己

    当与A关联的资源B达到阈值后,就限流自己

    B惹事,A挂了

  • 配置A

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第10张图片

  • postman模拟并发密集访问testB

    访问testB成功
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第11张图片
    postman里新建多线程集合组

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第12张图片
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第13张图片

  • 测试

    大批量线程高并发访问B,导致A失效了

    A挂了

在这里插入图片描述

  • 流控效果

    1、直接->快速失败(默认的流控处理)

    ​ 直接失败,抛出异常 --> Blocked by Sentinel (flow limiting)

    ​ 源码 --> com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

    2、预热

    • 说明

      公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值

    • 官网

      限流 冷启动

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第14张图片
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第15张图片
默认coldFactor为3,即请求QPS从threshold/3开始,经预热时长逐渐升至设定的QPS阈值。

  • 源码

    com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController

在这里插入图片描述

  • Warmup配置
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第16张图片

  • 测试

    多次点击http://localhost:8401/testB

    刚开始不行,后续慢慢OK

  • 应用场景

在这里插入图片描述

  • 排队等待

    1、匀速排队,阈值必须设置为QPS

    2、官网

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第17张图片
在这里插入图片描述
3、源码

com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

4、测试

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第18张图片
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第19张图片

5、降级规则

  • 基本介绍

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第20张图片
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第21张图片

进一步说明

在这里插入图片描述

Sentinel的断路器是没有半开状态的

半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。具体可以参考Hystrix

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第22张图片

  • 降级策略实战

    1、RT

    • 是什么

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第23张图片

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第24张图片

  • 测试

    1、代码

        @GetMapping("/testD")
        public String testD()
        {
            try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            log.info("testD 测试RT");
    
            return "------testD";
        }
    

    2、配置

    2毫秒内处理请求,否则断电,时间窗口1秒后恢复

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第25张图片

3、jmeter

http://localhost:8401/testD

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第26张图片

**启动**

在这里插入图片描述
关闭
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第27张图片

2、异常比例

是什么

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

代码

@GetMapping("/testD")
    public String testD()
    {

        log.info("testD 测试RT");
        int age = 10/0;
        return "------testD";
    }

配置

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第28张图片
jmeter

并发访问http://localhost:8401/testD大于5个
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第29张图片

结论

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第30张图片

3、异常数

是什么

异常数是按照分钟统计的

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第31张图片

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第32张图片

测试

  • 代码

    @GetMapping("/testE")
    public String testE()
    {
        log.info("testE 测试异常数");
        int age = 10/0;
        return "------testE 测试异常数";
    }
    
  • 配置

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第33张图片
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第34张图片

6、热点key限流

1、基本介绍

​ 官网

@SentinelResource
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第35张图片
代码

com.alibaba.csp.sentinel.slots.block.BlockException

@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                         @RequestParam(value = "p2",required = false) String p2) {
    //int age = 10/0;
    return "------testHotKey";
}
 
//兜底方法
public String deal_testHotKey (String p1, String p2, BlockException exception){
    return "------deal_testHotKey,o(╥﹏╥)o";  
}

@SentinelResource(value = “testHotKey”)

异常打到了前台用户界面看不到,不友好

@SentinelResource(value = “testHotKey”,blockHandler = “deal_testHotKey”)@SentinelResource(value = “testHotKey”,blockHandler = “deal_testHotKey”)

方法testHostKey里面第一个参数只要QPS超过每秒1次,马上降级处理 用了我们自己定义的

配置

在这里插入图片描述
测试

http://localhost:8401/testHotKey?p1=abc error

http://localhost:8401/testHotKey?p1=abc&p2=33 error

http://localhost:8401/testHotKey?p2=abc right

结论

上述案例演示了第一个参数p1,当QPS超过1秒1次点击后马上被限流

2、参数例外项

  • 特殊情况

    超过1秒钟一个后,达到阈值1后马上被限流

    我们期望p1参数当它是某个特殊值时,它的限流值和平时不一样

    假如当p1的值等于5时,它的阈值可以达到200

  • 配置

    添加按钮不能忘
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第36张图片

  • 测试

    http://localhost:8401/testHotKey?p1=5 通过

    http://localhost:8401/testHotKey?p1=3 失败

    当p1等于5的时候,阈值变为200

    当p1不等于5的时候,阈值就是平常的1

  • 前提条件

    热点参数的注意点,参数必须是基本类型或者String

  • 其他
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第37张图片

7、系统规则

  • 是什么

    官网

  • 各项配置参数说明
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第38张图片

  • 配置全局QPS

8、@SentinelResource

1、按资源名称限流+后续处理

  • 修改cloudalibaba-sentinel-service8401

  • POM

    <dependency>
        <groupId>com.atguigu.springcloudgroupId>
        <artifactId>cloud-api-commonartifactId>
        <version>${project.version}version>
    dependency>
    
  • yml

    server:
      port: 8401
    
    spring:
      application:
        name: cloudalibaba-sentinel-service
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
        sentinel:
          transport:
            dashboard: localhost:8080
            port: 8719  #默认8719,假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
    
  • 业务类RateLimitController

    @RestController
    public class RateLimitController
    {
        @GetMapping("/byResource")
        @SentinelResource(value = "byResource",blockHandler = "handleException")
        public CommonResult byResource()
        {
            return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
        }
        public CommonResult handleException(BlockException exception)
        {
            return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
        }
    
  • 主启动

    @EnableDiscoveryClient
    @SpringBootApplication
    public class MainApp8401
    {
        public static void main(String[] args) {
            SpringApplication.run(MainApp8401.class, args);
        }
    }
    
  • 配置流控规则

    配置步骤

在这里插入图片描述

表示1秒钟内查询次数大于1,就跑到我们自定义的处流,限流

  • 测试

    1秒钟点击1下,OK

    超过上述问题,疯狂点击,返回了自己定义的限流处理信息,限流发送

在这里插入图片描述

  • 额外问题

此时关闭微服务8401看看

Sentinel控制台,流控规则消失了????? 临时的

2、按照Url地址限流+后续处理

通过访问的URL来限流,会返回Sentinel自带默认的限流处理信息

业务类RateLimitController

@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl()
{
    return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));
}

控制台配置

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第39张图片
测试:

疯狂点击http://localhost:8401/rateLimit/byUrl
微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第40张图片

上面兜底方法存在的问题

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第41张图片

3、客户自定义限流处理逻辑

  • 创建customerBlockHandler类用于自定义限流处理逻辑

  • 自定义限流处理类

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第42张图片

package com.atguigu.springcloud.alibaba.myhandler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entities.*;

public class CustomerBlockHandler {

    public static CommonResult handleException(BlockException exception) {
        return new CommonResult(2020, "自定义限流处理信息....CustomerBlockHandler");

    }
}
  • RateLimitController

    @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException2")
    public CommonResult customerBlockHandler()
    {
        return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003"));
    }
     
    
  • 启动微服务后先调用一次

    http://localhost:8401/rateLimit/customerBlockHandler

  • Sentinel控制台配置

在这里插入图片描述

  • 测试

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第43张图片

  • 进一步说明

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第44张图片

4、更多注解属性说明

  • 代码配置

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第45张图片

  • 注解

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第46张图片

  • Sentinel主要有三个核心API

    SphU定义资源

    Tracer定义统计

    ContextUtil定义了上下文

9、服务熔断功能

sentinel整合ribbon+openFeign+fallback

Ribbon系列

1、提供者9003/9004

  • 新建cloudalibaba-provider-payment9003/9004

  • POM

    <dependencies>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
        <dependency>
            <groupId>com.atguigu.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>${project.version}version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>
    
    
  • yml

    server:
      port: 9003
    
    spring:
      application:
        name: nacos-payment-provider
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 #配置Nacos地址
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
    
  • 主启动类

    @SpringBootApplication
    @EnableDiscoveryClient
    public class PaymentMain9003
    {
        public static void main(String[] args) {
            SpringApplication.run(PaymentMain9003.class, args);
        }
    }
    
  • 业务类

    public class PaymentController
    {
        @Value("${server.port}")
        private String serverPort;
    
        public static HashMap<Long, Payment> hashMap = new HashMap<>();
        static{
            hashMap.put(1L,new Payment(1L,"28a8c1e3bc2742d8848569891fb42181"));
            hashMap.put(2L,new Payment(2L,"bba8c1e3bc2742d8848569891ac32182"));
            hashMap.put(3L,new Payment(3L,"6ua8c1e3bc2742d8848569891xt92183"));
        }
    
        @GetMapping(value = "/paymentSQL/{id}")
        public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
            Payment payment = hashMap.get(id);
            CommonResult<Payment> result = new CommonResult(200,"from mysql,serverPort:  "+serverPort,payment);
            return result;
        }
    }
    
  • 测试地址

    http://localhost:9003/paymentSQL/1

    2、消费者84

    • 新建cloudalibaba-consumer-nacos-order84

    • POM

         <dependencies>
              <dependency>
                  <groupId>org.springframework.cloudgroupId>
                  <artifactId>spring-cloud-starter-openfeignartifactId>
              dependency>
              <dependency>
                  <groupId>com.alibaba.cloudgroupId>
                  <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
              dependency>
              <dependency>
                  <groupId>com.alibaba.cloudgroupId>
                  <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
              dependency>
              <dependency>
                  <groupId>com.atguigu.springcloudgroupId>
                  <artifactId>cloud-api-commonsartifactId>
                  <version>${project.version}version>
              dependency>
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-webartifactId>
              dependency>
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-actuatorartifactId>
              dependency>
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-devtoolsartifactId>
                  <scope>runtimescope>
                  <optional>trueoptional>
              dependency>
              <dependency>
                  <groupId>org.projectlombokgroupId>
                  <artifactId>lombokartifactId>
                  <optional>trueoptional>
              dependency>
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-testartifactId>
                  <scope>testscope>
              dependency>
          dependencies>
      
    • yml

      server:
        port: 84
      
      
      spring:
        application:
          name: nacos-order-consumer
        cloud:
          nacos:
            discovery:
              server-addr: localhost:8848
          sentinel:
            transport:
              dashboard: localhost:8080
              port: 8719
      
      service-url:
        nacos-user-service: http://nacos-payment-provider
      
    • 主启动

      @EnableDiscoveryClient
      @SpringBootApplication
      @EnableFeignClients
      public class OrderNacosMain84
      {
          public static void main(String[] args) {
              SpringApplication.run(OrderNacosMain84.class, args);
          }
      }
      
    • 业务类

      ApplicationContextConfig

      @Configuration
      public class ApplicationContextConfig
      {
          @Bean
          @LoadBalanced
          public RestTemplate getRestTemplate()
          {
              return new RestTemplate();
          }
      }
      

      CircleBreakerController

      package com.atguigu.springcloud.alibaba.controller;
      
      import com.alibaba.csp.sentinel.annotation.SentinelResource;
      import com.alibaba.csp.sentinel.slots.block.BlockException;
      import com.atguigu.springcloud.alibaba.entities.CommonResult;
      import com.atguigu.springcloud.alibaba.entities.Payment;
      
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.client.RestTemplate;
      
      import javax.annotation.Resource;
      
      
      @RestController
      @Slf4j
      public class CircleBreakerController {
         
          public static final String SERVICE_URL = "http://nacos-payment-provider";
      
          @Resource
          private RestTemplate restTemplate;
      
         
          
          @RequestMapping("/consumer/fallback/{id}")
          //@SentinelResource(value = "fallback") //没有配置
          //@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
          //@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
          @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
                  exceptionsToIgnore = {IllegalArgumentException.class})
          public CommonResult<Payment> fallback(@PathVariable Long id) {
              CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id, CommonResult.class,id);
      
              if (id == 4) {
                  throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
              }else if (result.getData() == null) {
                  throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
              }
      
              return result;
          }
        
          //fallback
          public CommonResult handlerFallback(@PathVariable  Long id,Throwable e) {
              Payment payment = new Payment(id,"null");
              return new CommonResult<>(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);
          }
        
          //blockHandler
          public CommonResult blockHandler(@PathVariable  Long id,BlockException blockException) {
              Payment payment = new Payment(id,"null");
              return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);
          }
      }
      

      没有任何配置

      @RestController
      @Slf4j
      public class CircleBreakerController
      {
          public static final String SERVICE_URL = "http://nacos-payment-provider";
      
          @Resource
          private RestTemplate restTemplate;
      
          @RequestMapping("/consumer/fallback/{id}")
          @SentinelResource(value = "fallback")
      
          public CommonResult<Payment> fallback(@PathVariable Long id)
          {
              CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id);
      
              if (id == 4) {
                  throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
              }else if (result.getData() == null) {
                  throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
              }
      
              return result;
          }
      

      微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第47张图片

    忽略属性

    编码(那个业务类下面的CircleBreakerController的全部源码)
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第48张图片

Feign系列

1、修改84模块

  • pom

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
    
  • yml

    server:
      port: 84
    
    
    spring:
      application:
        name: nacos-order-consumer
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
        sentinel:
          transport:
            dashboard: localhost:8080
            port: 8719
    
    service-url:
      nacos-user-service: http://nacos-payment-provider
    
    #对Feign的支持
    feign:
      sentinel:
        enabled: true
    

    2、业务类

  • 带@FeignClient注解的业务接口

    @FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
    public interface PaymentService
    {
        @GetMapping(value = "/paymentSQL/{id}")
        public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
    }
    
  • fallback = PaymentFallbackService.class

  • PaymentFallbackService实现类

    Component
    public class PaymentFallbackService implements PaymentService
    {
        @Override
        public CommonResult<Payment> paymentSQL(Long id)
        {
            return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
        }
    }
    
  • Controller

    // OpenFeign
    @Resource
    private PaymentService paymentService;
    
    @GetMapping(value = "/consumer/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
        return paymentService.paymentSQL(id);
    }
    
  • 主启动

    添加@EnableFeignClients启动Feign的功能

    @EnableDiscoveryClient
    @SpringBootApplication
    @EnableFeignClients
    public class OrderNacosMain84
    {
        public static void main(String[] args) {
            SpringApplication.run(OrderNacosMain84.class, args);
        }
    }
    
  • 测试

    http://lcoalhost:84/consumer/paymentSQL/1

    测试84调用9003,此时故意关闭9003微服务提供者,看84消费侧自动降级,不会被耗死

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第49张图片

熔断框架比较

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第50张图片

10、规则持久化

  • 是什么

    一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化

  • 怎么玩

    将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上Sentinel上的流控规则持续有效

  • 步骤

    1、修改cloudalibaba-sentinel-service8401

    2、pom

    <dependency>
        <groupId>com.alibaba.cspgroupId>
        <artifactId>sentinel-datasource-nacosartifactId>
    dependency>
    

    3、yml

    server:
      port: 8401
    
    spring:
      application:
        name: cloudalibaba-sentinel-service
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 #Nacos服务注册中心地址
        sentinel:
          transport:
            dashboard: localhost:8080 #配置Sentinel dashboard地址
            port: 8719
          datasource:
            ds1:
              nacos:
                server-addr: localhost:8848
                dataId: cloudalibaba-sentinel-service
                groupId: DEFAULT_GROUP
                data-type: json
                rule-type: flow
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
    
    feign:
      sentinel:
        enabled: true # 激活Sentinel对Feign的支持
    

    添加了数据源

    spring:
       cloud:
        sentinel:
        datasource:
         ds1:
          nacos:
            server-addr:localhost:8848
            dataid:${spring.application.name}
            groupid:DEFAULT_GROUP
            data-type:json
                rule-type:flow
    

    4、添加Nacos业务规则配置
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第51张图片
    微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第52张图片
    内容解析

    [
        {
             "resource": "/retaLimit/byUrl",
             "limitApp": "default",
             "grade":   1,
             "count":   1,
             "strategy": 0,
             "controlBehavior": 0,
             "clusterMode": false    
        }
    ]
    

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第53张图片

5、测试

启动8401后刷新sentinel发现业务规则有了

  • 快速访问测试接口

    http://localhost:8401/rateLimit/byUrl

微服务SpringCloud开弓之SpringCloud Alibaba Sentinel实现熔断与限流「十四」_第54张图片

  • 停止8401再看sentinel

    配置规则消失

  • 重新启动8401再看sentinel

    多次调用 http://localhost:8401/rateLimit/byUrl

    重新配置出现了,持久化验证通过

你可能感兴趣的:(springCloud,java)