• Sentinel


    高并发系统关注的问题

    在这里插入图片描述
    在这里插入图片描述
    高并发系统关注的问题

    1. 独立部署,把高并发系统(例如:秒杀系统)放在单独的模块中
    2. 秒杀链接加密,例如,可以给秒杀商品加随机码,只有随机码正确,才进行后面的逻辑,随机码只有在到了秒杀时间才返回给用户
    3. 库存预热,例如,把商品放在redis中,通过信号量来决定是否能扣减
    4. 动静分离,例如,静态内容直接在nginx中处理
    5. 恶意请求拦截,例如,登录拦截器,风控系统
    6. 流量错峰,例如,验证码
    7. 限流熔断降级,例如,使用sentinel
    8. 消息队列,秒杀成功的请求放入队列进行处理
    • 1~6,8保证快,7保证稳

    熔断、降级、限流

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

    文档

    sentinel配置

    Hystrix与Sentinel
    在这里插入图片描述

    基本配置

    pom

    		
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-actuatorartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    yaml

    spring:
        sentinel:
          transport:
            dashboard: localhost:8080 #配置Sentinel dashboard地址
            port: 8719 #指定客户端监控 API 的端口(默认是 8719)
    
    feign:
      sentinel:
        enabled: true # 激活Sentinel对Feign的支持
    management:
      endpoints:
        web:
          exposure:
            include: *
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    main

    • @EnableDiscoveryClient

    可视化界面:

    持久化

    spring:
      cloud:
        sentinel:
          transport:
            dashboard: localhost:8080 #配置Sentinel dashboard地址
            port: 8719
          datasource: #添加Nacos数据源配置
            ds1:
              nacos:
                server-addr: localhost:8848
                dataId: cloudalibaba-sentinel-service
                groupId: DEFAULT_GROUP
                data-type: json
                rule-type: flow
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    json样例:

    [{
        "resource": "/rateLimit/byUrl",
        "IimitApp": "default",
        "grade": 1,
        "count": 1, 
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    解释:
    resource:资源名称;
    limitApp:来源应用;
    grade:阈值类型,0表示线程数, 1表示QPS;
    count:单机阈值;
    strategy:流控模式,0表示直接,1表示关联,2表示链路;
    controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;
    clusterMode:是否集群。

    例子

    定义资源

    官网:https://sentinelguard.io/zh-cn/docs/quick-start.html

    基于代码
        // 1.5.0 版本开始可以直接利用 try-with-resources 特性
        try (Entry entry = SphU.entry("HelloWorld")) {
            // 被保护的逻辑
            System.out.println("hello world");
    	} catch (BlockException ex) {
                // 处理被流控的逻辑
    	    System.out.println("blocked!");
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    基于注解

    使用@SentinelResource注解可以定义一个资源,例如

    @SentinelResource("HelloWorld")
    public void helloWorld() {
        // 资源中的逻辑
        System.out.println("hello world");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    @SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource 注解包含以下属性:

    • value:资源名称,必需项(不能为空)
    • entryType:entry 类型,可选项(默认为 EntryType.OUT
    • blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
    • fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
      • 返回值类型必须与原函数返回值类型一致;
      • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
      • fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
    • defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
      • 返回值类型必须与原函数返回值类型一致;
      • 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
      • defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
    • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
    示例:
    • 分别使用注解和try-with-resource定义资源:
      在这里插入图片描述
    • 在sentinel控制台能够对这两个资源进行操作:
      在这里插入图片描述

    RestTemplate

    @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")//若blockHandler和fallback 都进行了配置,则被限流降级而抛出BlockException时只会进入blockHandler处理逻辑。
        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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    Feign

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

    • 配置文件打开 Sentinel 对 Feign 的支持:feign.sentinel.enabled=true

    • 加入 spring-cloud-starter-openfeign 依赖使 Sentinel starter 中的自动化配置类生效:

      <dependency>
          <groupId>org.springframework.cloudgroupId>
          <artifactId>spring-cloud-starter-openfeignartifactId>
      dependency>
      
      • 1
      • 2
      • 3
      • 4

    这是一个 FeignClient 的简单使用示例:

    @FeignClient(name = "service-provider", fallback = EchoServiceFallback.class)
    public interface EchoService {
        @GetMapping("/echo/{str}")
        String echo(@PathVariable("str") String str);
    }
    
    //必须加入容器
    @Component
    class EchoServiceFallback implements EchoService {
        @Override
        public String echo(@PathVariable("str") String str) {
            return "echo fallback";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Gateway

    在这里插入图片描述
    官网:

    配置:
    1、pom引入:

    <dependency>
       <groupId>com.alibaba.cloudgroupId>
       <artifactId>spring-cloud-alibaba-sentinel-gatewayartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    2、配置文件

    spring.cloud.sentinel.transport.port=8379
    spring.cloud.sentinel.transport.dashboard=localhost:8080
    
    • 1
    • 2

    3、可以在 GatewayCallbackManager 注册回调进行定制:

    • setBlockHandler:注册函数用于实现自定义的逻辑处理被限流的请求,对应接口为 BlockRequestHandler。默认实现为 DefaultBlockRequestHandler,当被限流时会返回类似于下面的错误信息:Blocked by Sentinel: FlowException

      例如:

    • 自定义限流后的提示信息:
      @Configuration
      public class MyGatewayCallbackManager {
          public MyGatewayCallbackManager() {
              GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
                  @Override
                  public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {
                      String jsonResp = "自定义限流返回信息";
                      
                      Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(jsonResp), String.class);
                      return body;
                  }
              });
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
  • 相关阅读:
    js:Class对象中的函数,在使用 this 时理解
    【S1002基于vue+nodejs的学生竞赛报名管理系统-哔哩哔哩】 https://b23.tv/xhyyT9U
    操作系统课程设计:新增Linux驱动程序(重制版)
    书生浦语大模型实战营---Linux 基础知识
    中间件漏洞 | Apache-SSI/任意命令执行
    qt6 多媒体开发代码分析(一)
    SiO2/KH550修饰四氧化三铁纳米磁性颗粒|PDA包裹四氧化三铁磁性纳米颗粒(科研级)
    满满干货:分享2个实用的PDF编辑文字方法
    Jmeter电商系统压测实战<二>
    家用洗地机什么牌子最好用?2023年洗地机排行榜
  • 原文地址:https://blog.csdn.net/m0_55155505/article/details/125764340