SpringCloud-Alibaba之Sentinel(1)流控

学习SpringCloud的日常Demo

Sentinel基本介绍

Sentinel: 分布式系统的流量哨兵
Sentinel 具有以下特征:

  • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

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

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
    完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

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

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
    完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
    SpringCloud-Alibaba之Sentinel(1)流控_第1张图片

安装使用

SpringCloud-Alibaba之Sentinel(1)流控_第2张图片
SpringCloud-Alibaba之Sentinel(1)流控_第3张图片

cloudalibaba-sentinel-service8401模块构建

目录结构

SpringCloud-Alibaba之Sentinel(1)流控_第4张图片

POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.mineok.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mineok.springcloud</groupId>
    <artifactId>cloudalibaba-sentinel-service8401</artifactId>

    <dependencies>
        <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
            <groupId>com.mineok.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件+actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--日常通用jar包配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>
</project>
application.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的支持
Controller
@RestController
@Slf4j
public class FlowLimitController {
    @GetMapping("/testA")
    public String testA() {
//        try {
//            TimeUnit.SECONDS.sleep(3);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return "------testA";
    }

    @GetMapping("/testB")
    public String testB() {
        log.info(Thread.currentThread().getName()+" "+"...testB");
        log.info(Thread.currentThread().getName() + "\t" + "...testB");
        return "------testB";
    }


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

        log.info("testD 异常比例");
        int age = 10 / 0;
        return "------testD";
    }

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

    @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";  //sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
    }

}
测试

SpringCloud-Alibaba之Sentinel(1)流控_第5张图片

流控规则

SpringCloud-Alibaba之Sentinel(1)流控_第6张图片

  • 资源名:
    唯一名称,默认请求路径

  • 针对来源:
    Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)

  • 阈值类型/单机阈值:
    1.QPS(每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流
    2.线程数:当调用该api的线程数达到阈值的时候,进行限流
    是否集群:(不)需要集群

  • 流控模式:
    1.直接:api达到限流条件时,直接限流
    2.关联:当关联的资源达到阈值时,就限流自己
    2.链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)

  • 流控效果:
    1.快速失败:直接失败,抛异常
    2.Warm Up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。
    3.排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS。否则无效。

流控效果——快速失败

直接快速失败

SpringCloud-Alibaba之Sentinel(1)流控_第7张图片
表示允许1秒钟内查询1次,若超过次数1,就直接快速失败,报默认错误
SpringCloud-Alibaba之Sentinel(1)流控_第8张图片

切换阈值类型为线程数

SpringCloud-Alibaba之Sentinel(1)流控_第9张图片
每次只允许一个线程进来访问服务,其他线程在外面等待

关联快速失败
  • 当关联的资源达到阈值时,就限流自己
  • 当与A关联的资源B达到阀值后,就限流A自己
    SpringCloud-Alibaba之Sentinel(1)流控_第10张图片
    POSTMAN模拟并发访问/testB
    SpringCloud-Alibaba之Sentinel(1)流控_第11张图片
    SpringCloud-Alibaba之Sentinel(1)流控_第12张图片
    可以看到/testB访问满了后,/testA直接挂了

流控效果——Warm Up

Warm Up方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过“冷启动”,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
SpringCloud-Alibaba之Sentinel(1)流控_第13张图片

流控效果——排队等待

匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。
设置含义: /testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。
这种方式:主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景, 在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
SpringCloud-Alibaba之Sentinel(1)流控_第14张图片

测试

POSTMAN模拟并发访问/testB
SpringCloud-Alibaba之Sentinel(1)流控_第15张图片
SpringCloud-Alibaba之Sentinel(1)流控_第16张图片

GitHub:SpringCloud日常Demo

你可能感兴趣的:(Spring全家桶)