Sentinel实现熔断和限流

一、概述

1、简介

​ 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。github地址:https://github.com/alibaba/Sentinel 。具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

2、主要特性

3、下载地址:https://github.com/alibaba/Sentinel/releases 。下载好后在命令行窗口执行 java -jar sentinel-dashboard-xxx.jar即可(xxx是下载的版本号),在浏览器地址栏输入http://localhost:8080看到以下界面,便安装成功。账号密码都是 sentinel 。

二、初始化监控工程

1、新建一个模块,在pom中添加以下依赖;

<dependencies>
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</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>
  <!--OpenFeign-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  <!--引入自己定义的包-->
  <dependency>
      <groupId>com.xhanglog.springcloud</groupId>
      <artifactId>cloud-api-commons</artifactId>
      <version>${project.version}</version>
  </dependency>

  <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>
  <!--热部署-->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
      <optional>true</optional>
  </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>

2、配置文件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 #默认8719端口,如果被占用会+1扫描,直到找到未被占用的端口

management:
endpoints:
  web:
    exposure:
      include: "*"

3、主启动类加上 @EnableDiscoveryClient 注解。

4、启动项目,发送一个请求,看sentinel控制台会出现如下图内容:

三、流控规则

1、增加流控规则的界面如下,官方文档地址:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

说明:

  • 资源名:唯一名称,默认请求路径;
  • 针对来源:Sentinel 可以对调用者进行限流,填写微服务名,默认default(不区分来源);
  • 阀值类型:
    • QPS(每秒钟请求数量):当调用该api的QPS达到阀值的时候,进行限流;
    • 线程数:当调用该api的线程数达到阀值的时候,进行限流;
  • 流控模式:
    • 直接:api达到限流条件时,直接限流;
    • 关联:当关联的资源达到阀值时就限流自己;
    • 链路:只记录指定链路上的流量(指定资源从入口进来的流量,如果达到阀值就进行限流);
  • 流控效果:
    • 快速失败:直接失败抛异常;
    • Warm Up:根据codeFactor(冷加载因子,默认3)的值,从阀值/codeFactor,经过预热时长才达到设置的QPS阀值;
    • 排队等待:匀速排队,让请求匀速通过,阀值类型必须设置为QPS,否则无效。

四、降级规则

​ 除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。增加降级规则界面如下,官网说明地址:https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

说明:

  • RT(平均响应时间):

    平均响应时间超出阀值且在时间窗口内通过的请求大于等于5时触发降级,时间窗口期过后会关闭断路器,RT最大为4900ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。

  • 异常比例(秒级):

    QPS >= 5,并且每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。时间窗口结束后关闭降级。

  • 异常数(分钟级):

    资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 时间窗口小于 60s,则结束熔断状态后仍可能再进入熔断状态。

五、热点 Key 限流

​ 统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。请求如下图,官网地址:https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81

配置举例:

  • 编写两个方法

    @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){
        return "************************testHotKey";
    }
    
    public String deal_testHotKey(String p1, String p2, BlockException exception){
        return "************************deal_testHotKey";
    }
    
  • 热点规则配置如下图;

  • 当浏览器没秒请求包含p1参数的次数超过1次,会执行deal_testHotKey的结果。

六、规则持久化

1、将sentinel的规则持久化到nacos中,在pom中引入以下依赖;

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

2、在配置文件中添加以下配置:

spring:
  cloud:
    sentinel:
      #将sentinel配置信息持久化到nacos
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

3、在nacos中加入配置,文件类型为json,dataId就是以上配置的dataId;

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

说明:

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

案例代码地址:https://github.com/xhanglog/springcloud-learning

猜你喜欢

转载自www.cnblogs.com/Mhang/p/12614912.html