欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringCloud——熔断与限流 Sentinel

程序员文章站 2022-07-15 09:19:09
...

1. Sentinel 概述

官网:https://github.com/alibaba/Sentinel

https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

1.1 功能

SpringCloud——熔断与限流 Sentinel

1.2 控制台安装

Sentinel 分为两个部分:

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

下载:

https://github.com/alibaba/Sentinel/releases

下载到本地 sentinel-dashboard-1.7.0.jar

运行:java -jar sentinel-dashboard-1.7.0.jar 

访问:http://localhost:8080   登录账号密码均为 sentinel

SpringCloud——熔断与限流 Sentinel

1.3 流控规则

SpringCloud——熔断与限流 Sentinel

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

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


阈值类型/单机阈值:

  • QPS (每秒钟的请求数量) :当调用该 api 的 QPS 达到阈值时,进行限流
  • 线程数:当调用该 api 的线程数达到阈值时,进行限流

流控模式:

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

流控效果:

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

1.4 降级规则

SpringCloud——熔断与限流 Sentinel

RT (平均响应时间)
平均响应时间超出阈值且在时间窗口内通过的请求>=5,两个条件同时满足后触发降级,窗口期过后关闭断路器。RT最大4900 (更大的需要通过Dcsp.sentinel.statisti .max.t=XXXX才能生效)

异常比列(秒级)
QPS>= 5且异常比例(秒级统计)超过阈值时触发降级,时间窗门结束后关闭降级。

异常数(分钟级)
异常数(分钟统计)超过阈值时触发降级,时间窗口结束后关闭降级。
 

1.5 热点限流

SpringCloud——熔断与限流 Sentinel

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

 

Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。

1.6 系统规则

SpringCloud——熔断与限流 Sentinel

Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

2. 熔断框架比较

SpringCloud——熔断与限流 Sentinel


 

3. 服务熔断

3.1 @SentinelResource

@SentinelResource 用于定义资源,并提供可选的异常处理和fallback配置项。

属性说明

value:

资源名称,必需项。因为需要通过resource name找到对应的规则。

entryType:

entry 类型,可选项,
有IN和OUT两个选项,默认为 EntryType.OUT。

public enum EntryType {
    IN("IN"),
    OUT("OUT");
}

blockHandler:

blockHandler 对应处理 BlockException 的函数名称,可选项。
blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,
参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。

blockHandlerClass:

blockHandler 函数默认需要和原方法在同一个类中,如果希望使用其他类的函数,
则需要指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

fallback:

fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。
fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。

fallbackClass:

fallbackClass的应用和blockHandlerClass类似,fallback 函数默认需要和原方法在同一个类中。
若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

defaultFallback(since 1.6.0):

如果没有配置defaultFallback方法,默认都会走到这里来。
默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑。
默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。

exceptionsToIgnore(since 1.6.0):

用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

3.2 实现服务熔断

pom:

<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>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

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,如果被占用从 8719 开始依次 +1 扫描,直至找到未被占用的端口
management:
    endpoints:
        web:
            exposure:
                include: '*'

主启动:

@SpringBootApplication
@EnableDiscoveryClient
public class MainApp8401 {
    public static void main(String[] args){
        SpringApplication.run(MainApp8401.class,args);
    }
}

业务类:

@RestController
public class RateLimitController {
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handleException",
            fallback = "byResourceFallback")
    public String byResource()
    {
        return "按资源名称限流测试OK";
    }

    public String byResourceFallback()
    {
        return "服务降级返回";
    }
}

 

SpringCloud——熔断与限流 Sentinel

SpringCloud——熔断与限流 Sentinel

流控规则:

SpringCloud——熔断与限流 Sentinel

测试:

SpringCloud——熔断与限流 Sentinel

业务类添加异常:

SpringCloud——熔断与限流 Sentinel

 

4. 规则持久化

重启服务后,Sentinel 中对应的规则将消失,生产环境需要将配置规则进行持久化。

实现:将限流配置规则持久化进 Nacos 保存,只要 Nacos 里面的配置不删除,对应服务在 Sentinel 上的流控规则持续有效。

pom:

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

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,如果被占用从 8719 开始依次 +1 扫描,直至找到未被占用的端口
            datasource:
                ds1:    #  数据源1
                    nacos:
                        server-addr: localhost:8848
                        dataId: cloudalibaba-sentinel-service   # 微服务名称
                        groupId: DEFAULT_GROUP
                        data-type: json
                        rule-type: flow

management:
    endpoints:
        web:
            exposure:
                include: '*'

Nacos 中添加规则配置:

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

 

SpringCloud——熔断与限流 Sentinel

 

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

启动服务就可以在 sentinel 中看见规则了:

SpringCloud——熔断与限流 Sentinel