• Spring Cloud Alibaba Sentinel流量防卫兵


    Spring Cloud Alibaba Sentinel流量防卫兵

    1. 分布式遇到的问题

    服务可用性问题
    在这里插入图片描述

    服务可用性场景
    在这里插入图片描述

    服务雪崩效应
    因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应导致服务不可用的原因:
    在这里插入图片描述

    在服务提供者不可用的时候,会出现大量重试的情况:用户重试、代码逻辑重试,这些重试最终导致:进一步加大请求流量。所以归根结底导致雪崩效应的最根本原因是:大量请求线程同步等待造成的资源耗尽。当服务调用者使用同步调用时, 会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了。

    2.解决的方法

    • 超时机制
      在不做任何处理的情况下,服务提供者不可用会导致消费者请求线程强制等待,而造成系统资源耗尽。加入超时机制,一旦超时,就释放资源。由于释放资源速度较快,一定程度上可以抑制资源耗尽的问题。

    • 服务限流
      设置阈值,操作临界值不再进行向后端请求.

    • 隔离
      每当向服务发起一个请求时,就是会发起一个http请求,每一个http请求就要开启一个线程,然后等待服务返回信息,这容易导致线程的堆积,所以就可以用http的URI作为一个标识,然后相同的URI可以开启一个线程池,然后线程池中限定线程数,这样就可以设置拒绝策略,当线程池满了,就可以快速的抛出异常或者拒绝请求,用线程池做到线程隔离来达到限流。

    • 服务熔断

      熔断就是有一个阈值,向服务发起请求后,如果不成功,就会记录次数,然后当连续失败次数达到阈值时,下次请求的时候就会直接把这个服务停止。请求有三种状态,可以请求(开),不可请求(关),还有一个中间状态,相当于半开状态,半开状态是什么意思呢,就是可以尝试着去请求,就可以在关闭状态后一段时间,发一个请求尝试一下是否可以请求成功,如果不成功,继续保持关闭状态,如果请求成功,则变成开放状态。

    • 服务降级
      降级其实就相当于,当我们向一个服务发起请求,当请求超时了,就会把这次请求记录到服务中,然后就会尝试向其他服务发请求,如果还没成功,就对这次请求进行处理(怎么处理取决于业务需求如)就相当于try
      catch一样的逻辑,当然Sentinel底层使用aop来实现的。

    Sentinel: 分布式系统的流量防卫兵

    点击进入官方文档

    1. 简介和特折

    • Sentinel 介绍 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel
      是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
    • Sentinel具有以下特征:
      1. 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
      2. 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
      3. 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
      4. 完善的 SPI
        扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等

    Sentinel流量防卫兵的搭建

    1.引入依赖

    在这里插入图片描述

    <dependency>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-core</artifactId>
         <version>1.8.0</version>
    </dependency>
    <dependency>
    
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-annotation-aspectj</artifactId>
        <version>1.8.0</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.添加配置类

    这里的配置类也就是aop增强的时候所用的切点,但是这里用的时@Bean注入而不是 注解

    @Configuration
    public class SentinelConfig {
    
        @Bean
        public SentinelResourceAspect sentinelResourceAspect() {
            return new SentinelResourceAspect();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.运行类上添加@SentinelResource,并配置blockHandler和fallback

    在这里插入图片描述

    @RestController
    public class UserController {
    
        @GetMapping("/user/{id}")
        @SentinelResource(value = "findOrderByUserId",
                fallback = "fallback", fallbackClass = UserController.class,
                blockHandler = "handleException", blockHandlerClass = UserController.class
        )
        public String findOrderByUserId(@PathVariable("id") Integer id) {
    
            if (id == 4) {
                throw new IllegalArgumentException("非法参数异常");
            }
    
            return "正常返回";
        }
    
        public static String fallback(Integer id, Throwable e) {
            return "===被异常降级啦===";
        }
    
        public static String handleException(Integer id, BlockException e) {
            return "===被限流啦===";
        }
    
        /**
         * 定义流控规则
         */
        @PostConstruct
        private static void initFlowRules() {
            List<FlowRule> rules = new ArrayList<>();
            FlowRule rule = new FlowRule();
            //设置受保护的资源
            rule.setResource("findOrderByUserId");
            // 设置流控规则 QPS
            rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
            // 设置受保护的资源阈值
            // Set limit QPS to 20.
            rule.setCount(1);
            rules.add(rule);
            // 加载配置好的规则
            FlowRuleManager.loadRules(rules);
        }
    }
    
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    4. linux中放入Sentinel控制台程序jar包,并执行

    不让上传自己去外网下把这是网址
    1.8.0版本

    linux启动代码

    java -Dserver.port=8858 -Dsentinel.dashboard.auth.username=sentinel
    -Dsentinel.dashboard.auth.password=123456 -jar sentinel-dashboard-1.8.0.jar

    应用接入控制台(可选下面那种,简单)

    控制台加入jar包

    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-transport-simple-http</artifactId>
        <version>1.8.0</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    写入参数
    在这里插入图片描述
    控制台
    访问地址 虚拟机IP/设置的端口号 (8858)账号刚刚设置sentinel,密码123456
    不出现这个也会正常,看一下机器列表有没有你就行啦,毕竟开源要什么自行车
    在这里插入图片描述

    1.使用整合包(这种)

    一个依赖即可
    可去掉上方加入的三个jar包,嫌麻烦不去除也可

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

    配置文件

    # 添加sentinel的控制台地址
    spring.cloud.sentinel.transport.dashboard=127.0.0.1:8858
    
    # 可以理解为应用端的端口号 服务端是上面配置的8858
    # 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer, 可以省略
    spring.cloud.sentinel.transport.port=8719
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    直接运行即可

    2.通过nacos持久化

    引入依赖

            <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    新建一个bootstrp.properties文件
    在这里插入图片描述

    spring.cloud.nacos.config.server-addr=192.168.14.58:8848
    #spring.application.name=sentinel-app
    spring.cloud.sentinel.transport.dashboard=192.168.14.58:8858
    spring.cloud.sentinel.datasource.flow.nacos.serverAddr=192.168.14.58:8848
    spring.cloud.sentinel.datasource.flow.nacos.dataId=${spring.application.name}-flow-rules
    spring.cloud.sentinel.datasource.flow.nacos.groupId=DEFAULT_GROUP
    spring.cloud.sentinel.datasource.flow.nacos.data-type=json
    spring.cloud.sentinel.datasource.flow.nacos.rule-type=flow
    spring.cloud.sentinel.datasource.degrade.nacos.serverAddr=192.168.14.58:8848
    spring.cloud.sentinel.datasource.degrade.nacos.dataId=${spring.application.name}-degrade-rules
    spring.cloud.sentinel.datasource.degrade.nacos.groupId=DEFAULT_GROUP
    spring.cloud.sentinel.datasource.degrade.nacos.data-type=json
    spring.cloud.sentinel.datasource.degrade.nacos.rule-type=degrade
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在nacos中创建 就是前面建立的点击跳转
    在这里插入图片描述

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

    3.设置规则 json

    流量控制

    [
      {
        // 资源名
        "resource": "/test",
        // 针对来源,若为 default 则不区分调用来源
        "limitApp": "default",
        // 限流阈值类型(1:QPS;0:并发线程数)
        "grade": 1,
        // 阈值
        "count": 1,
        // 是否是集群模式
        "clusterMode": false,
        // 流控效果(0:快速失败;1:Warm Up(预热模式);2:排队等待)
        "controlBehavior": 0,
        // 流控模式(0:直接;1:关联;2:链路)
        "strategy": 0,
        // 预热时间(秒,预热模式需要此参数)
        "warmUpPeriodSec": 10,
        // 超时时间(排队等待模式需要此参数)
        "maxQueueingTimeMs": 500,
        // 关联资源、入口资源(关联、链路模式)
        "refResource": "rrr"
      }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    降级规则

    [
      {
      	// 资源名
        "resource": "/test1",
        "limitApp": "default",
        // 熔断策略(0:慢调用比例,1:异常比率,2:异常计数)
        "grade": 0,
        // 最大RT、比例阈值、异常数
        "count": 200,
        // 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)
        "slowRatioThreshold": 0.2,
        // 最小请求数
        "minRequestAmount": 5,
        // 当单位统计时长(类中默认1000)
        "statIntervalMs": 1000,
        // 熔断时长
        "timeWindow": 10
      }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    热点规则

    [
      {
      	// 资源名
        "resource": "/test1",
        // 限流模式(QPS 模式,不可更改)
        "grade": 1,
        // 参数索引
        "paramIdx": 0,
        // 单机阈值
        "count": 13,
        // 统计窗口时长
        "durationInSec": 6,
        // 是否集群 默认false
        "clusterMode": 默认false,
        // 
        "burstCount": 0,
        // 集群模式配置
        "clusterConfig": {
          // 
          "fallbackToLocalWhenFail": true,
       	  // 
          "flowId": 2,
          // 
          "sampleCount": 10,
          // 
          "thresholdType": 0,
          // 
          "windowIntervalMs": 1000
        },
        // 流控效果(支持快速失败和匀速排队模式)
        "controlBehavior": 0,
        // 
        "limitApp": "default",
        // 
        "maxQueueingTimeMs": 0,
        // 高级选项
        "paramFlowItemList": [
          {
          	// 参数类型
            "classType": "int",
          	// 限流阈值
            "count": 222,
          	// 参数值
            "object": "2"
          }
        ]
      }
    ]
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    系统规则

    [
      {
      	// RT
        "avgRt": 1,
        // CPU 使用率
        "highestCpuUsage": -1,
        // LOAD
        "highestSystemLoad": -1,
        // 线程数
        "maxThread": -1,
        // 入口 QPS
        "qps": -1
      }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    授权规则

    [
      {
        // 资源名
        "resource": "sentinel_spring_web_context",
      	// 流控应用
        "limitApp": "/test",
        // 授权类型(0代表白名单;1代表黑名单。)
        "strategy": 0
      }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    微服务框架 SpringCloud微服务架构 3 Eureka 3.1 提供者与消费者
    【Java面试】@Resource 和 @Autowired 的区别
    Vatee万腾未来科技之航:Vatee创新引领的新纪元
    Docker学习笔记
    Windows10 子系统 (WSL) 或 docker wsl 模式 修改虚拟磁盘目录
    【mysql学习笔记29】触发器
    Python 获取进程PID
    【ASM】字节码操作 转换已有的类 在方法进入和退出的时候 添加
    springboot,spring框架返回204 status code的时候,会吞掉返回值
    如何实现一键全选
  • 原文地址:https://blog.csdn.net/weixin_63558979/article/details/133141270