SpringCloud——熔断与限流 Sentinel

1. Sentinel 概述

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

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

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

1.1 功能

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

1.3 流控规则

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

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


阈值类型/单机阈值:

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

流控模式:

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

流控效果:

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

1.4 降级规则

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

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

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

1.5 热点限流

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

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

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

 

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

1.6 系统规则

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

2. 熔断框架比较


 

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 "服务降级返回";
    }
}

 

流控规则:

测试:

业务类添加异常:

 

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    
    }
]

 

 

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

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

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值