Rubin's Blog

  • 首页
  • 关于作者
  • 隐私政策
享受恬静与美好~~~
分享生活的点点滴滴~~~
  1. 首页
  2. SpringCloud
  3. 正文

SpringCloud Alibaba之Sentinel

2021年 10月 25日 616点热度 0人点赞 0条评论

Sentinel介绍

Sentinel是一个面向云原生微服务的流量控制、熔断降级组件。替代Hystrix,针对问题:服务雪崩、服务降级、服务熔断、服务限流。

Sentinel 分为两个部分:

  • 核心库:(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持
  • 控制台:(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器

Sentinel 具有以下特征:

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

Sentinel 的主要特性:

Sentinel部署

下载地址:https://github.com/alibaba/Sentinel/releases 。我们使用v1.7.1。

启动:java -jar sentinel-dashboard-1.7.1.jar &

用户名/密码:sentinel/sentinel

服务集成

我们的服务集成Sentinel也很简单,只需要引入如下依赖:

<!--sentinel 核心环境依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependencyManagement>
    <dependencies>

        <!--SCA -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.1.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--SCA -->
    </dependencies>
</dependencyManagement>

添加上Sentinel的配置项:

spring:
  cloud: 
    sentinel:
      transport:
        # sentinel dashboard/console地址
        dashboard: 127.0.0.1:8080
        # sentinel会在该端口启动http server,那么这样的话,控制台定义的⼀些限流等规则才能发送传递过来
        # 如果8719端口被占⽤,那么会依次+1
        port: 8719

至此,我们的Sentinel就集成好了。我们可以发一个请求到该服务器,然后查看Sentinel Dashboard( 注意:Sentinel Dashboard 是懒加载的,不发起调用是没有数据的)。

Sentinel关键概念

概念名称概念描述
资源它可以是Java应用程序中的任何内容。例如:由应用程序提供的服务、由应用程序调用的其他应用提供的服务甚至可以是一段代码。我们请求对的API接口就是资源
规则围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整

Sentinel限流模块

我们系统的并发能力有限,如果太多请求过来,我们就应该进行流量控制。使用Sentinel设定限流规则的示例如下:

  • 资源名:默认是请求路径
  • 针对来源:Sentinel可以针对调用者进行限流,填写微服务名称,默认default(不区分来源)
  • 阈值类型和单机阈值:QPS(每秒钟请求数量)是指调用该资源的QPS达到阈值时进行限流;线程数是指当调用该资源的线程数达到阈值时进行限流(线程处理请求的时候,如果说业务逻辑执行时间很长,流量洪峰来临时,会耗费很多线程资源,这些线程资源会堆积起来造成服务的不可用,进一步就有可能影响的上游不可用而引发服务雪崩)
  • 是否集群:是否是集群限流
  • 流控模式:直接是指资源调用达到限流条件时,直接限流;关联是指关联的资源达到限流条件了就限流自己;链路是指只记录指定链路上的流量
  • 流控效果:快速失败是指直接失败,抛出异常;Warm Up是指根据冷加载因子(默认是3)的值,从阈值/冷加载因子,经过预热时长,才达到设置的QPS阈值;排队等待是指匀速排队,让请求匀速通过,阈值类型必须设置为QPS,否则无效

流控模式之关联限流

关联的资源调用达到阈值的时候限流自己。比如用户注册接口,需要调用身份证校验接口。如果身份证校验接口请求达到阈值,使用关联,就可以对用户注册接口也进行限流。

流控模式之链路限流

链路指的是请求链路(调用链)。链路模式下会控制资源所在的调用链路入口的流量。需要在规则中配置入口资源,即该调用链路入口的上下文名称。

上图中来自入口Entrance1和Entrance2的请求都调用到了资源NodeA,Sentinel允许只根据某个调用入口的统计信息对资源限流。比如链路模式下设置入口资源为Entrance1,则只有该入口的调用才会记录到NodeA的限流统计中,而不关心Entrance2的调用。

流控效果之Warm Up

当系统长期处于空闲的情况下,流量的突然增加会直接把系统拉升到高水位,从而可能瞬间压垮系统。比如电商网站的秒杀模块等等。

通过Warm Up模式可以让通过的流量缓慢增加,经过预热时间以后达到系统处理速率的设定值。这样,就避免了上述问题与风险,增加了系统的稳定性。

流控效果之排队等待

排队等待模式下会严格控制请求通过的间隔时间,即请求会匀速通过,允许部分请求排队等待,通常用于消息队列削峰填谷等场景。需设置具体的超时时间,当计算的等待时间超过超时时间时请求就会被拒绝。

很多流量过来了,并不是直接拒绝请求,而是请求进行排队,⼀个⼀个匀速通过(处理),请求能等就等着被处理,不能等(等待时间>超时时间)就会被拒绝。例如,QPS 配置为 5,则代表请求每 200 ms 才能通过⼀个,多出的请求将排队等待通过。超时时间代表最大排队时间,超出最大排队时间的请求将会直接被拒绝。排队等待模式下,QPS 设置值不要超过 1000(请求间隔 1 ms)。

Sentinel熔断降级

流控是对外部来的大流量进行控制,熔断降级的视⻆是对内部问题进行处理。Sentinel降级会在调用链路中某个资源出现不稳定状态时(调用超时或异常),就对着个资源的调用进行限制,让请求快速失败来避免影响到其他的资源。当资源被降级之后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(这里跟Hystrix不同,Sentinel没有自动修复功能,只能等到时间窗口内过完)。

降级策略之RT(平均响应时间)

当1秒内持续进入5个及以上的请求,平均响应时间超过了设定的阈值(以毫秒为单位),那么在接下来的时间窗口内(以秒为单位),对这个方法的调用就会直接抛出异常(DegradeException)。需要注意的是:Sentinel默认统计的RT上限是4900ms,超出此阈值都会算作4900ms。若需要更改此上限可以通过配置启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置。

降级策略之异常比例

当1秒内持续进入5个及以上的请求,并且每秒异常总数占通过量的比例超过阈值之后,资源进入降级状态。即在接下来的时间窗口内(以s为单位),岁这个方法的调用都会自动返回。 异常比率的阈值范围是 [0.0, 1.0] ,代表 0% - 100%。

降级策略之异常数

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

Sentinel自定义兜底逻辑

@SentinelResource注解类似于Hystrix中的@HystrixCommand注解。@SentinelResource注解中有两个属性需要我们进行区分,blockHandler属性用来指定不满足Sentinel规则的降级兜底方法,fallback属性用于指定Java运行时异常兜底方法。

@SentinelResource(value = "sentinel",
        blockHandlerClass = SentinelFallbackClass.class,
        blockHandler = "handleBlock",
        fallbackClass = SentinelFallbackClass.class,
        fallback = "handleException"
)
public String sentinel() {
    if (random.nextBoolean()) {
        int i = 3/0;
    }
    return irResumeService.hello();
}
package com.rubin.autodeliver.fallback;

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

public class SentinelFallbackClass {

    public static String handleBlock(BlockException blockException) {
        blockException.printStackTrace();
        return "被Sentinel限流了";
    }

    public static String handleException() {
        return "调用失败了,直接熔断";
    }

}

在这里需要注意,我们的兜底方法可以定义在本类,也可以定义在其他类。定义在本类或者其他类其参数和返回值均要跟原方法一致,但定义在外部类方法要定义为静态的。

基于Nacos实现Sentinel规则持久化

目前,Sentinel Dashboard中添加的规则数据存储在内存,微服务停掉规则数据就消失,在生产环境下不合适。我们可以将Sentinel规则数据持久化到Nacos配置中心,让微服务从Nacos获取规则数据。

我们需要在Sentinel微服务中添加如下依赖:

<!-- Sentinel⽀持采用 Nacos 作为规则配置数据源,引入该适配依赖 -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

将Sentinel配置修改如下:

spring:
  cloud: 
    sentinel:
      transport:
        # sentinel dashboard/console地址
        dashboard: 127.0.0.1:8080
        # sentinel会在该端口启动http server,那么这样的话,控制台定义的⼀些限流等规则才能发送传递过来
        # 如果8719端口被占⽤,那么会依次+1
        port: 8719
      # Sentinel Nacos数据源配置,Nacos中的规则会⾃动同步到sentinel控制台的流控规则中  
      datasource:
        # 此处的flow为⾃定义数据源名
        # 流控规则
        flow:
          nacos:
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
            data-id: ${spring.application.name}-flow-rules.json
            groupId: DEFAULT_GROUP
            data-type: json
            # 类型来⾃RuleType类
            rule-type: flow
        degrade:
          nacos:
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
            data-id: ${spring.application.name}-degrade-rules.json
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: degrade 

其中的namespace是我们自定义添加的命名空间,不填默认是public命名空间。我们在自定义的命名空间下添加如下配置项:

${spring.application.name} -flow-rules.json:

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

其所有属性来自源码FlowRule类:

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

${spring.application.name}-degrade-rules.json :

[
    {
        "resource":"sentinel",
        "grade":2,
        "count":1,
        "timeWindow":5
    }
]

其所有属性来自源码DegradeRule类:

  • resource:资源名称
  • grade:降级策略 0 RT 1 异常比例 2 异常数
  • count:阈值
  • timeWindow:时间窗

Rule 源码体系结构:

注意:

  1. ⼀个资源可以同时有多个限流规则和降级规则,所以配置集中是⼀个json数组
  2. Sentinel控制台中修改规则,仅是内存中生效,不会修改Nacos中的配置值,重启后恢复原来的值; Nacos控制台中修改规则,不仅内存中生效,Nacos中持久化规则也生效,重启后规则依然保持

以上就是关于Sentinel的全部内容。欢迎小伙伴们积极留言交流~~~

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: SpringCloud
最后更新:2022年 6月 9日

RubinChu

一个快乐的小逗比~~~

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • Sentinel介绍
  • Sentinel部署
  • 服务集成
  • Sentinel关键概念
  • Sentinel限流模块
    • 流控模式之关联限流
    • 流控模式之链路限流
    • 流控效果之Warm Up
    • 流控效果之排队等待
  • Sentinel熔断降级
    • 降级策略之RT(平均响应时间)
    • 降级策略之异常比例
    • 降级策略之异常数
    • Sentinel自定义兜底逻辑
  • 基于Nacos实现Sentinel规则持久化
最新 热点 随机
最新 热点 随机
问题记录之Chrome设置屏蔽Https禁止调用Http行为 问题记录之Mac设置软链接 问题记录之JDK8连接MySQL数据库失败 面试系列之自我介绍 面试总结 算法思维
Netty初探 数据结构之图 Dubbo之配置项说明 MyBatis之配置文件详解 Docker之数据卷 SSM整合

COPYRIGHT © 2021 rubinchu.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

京ICP备19039146号-1