SpringCloudAlibaba 服务保护 Sentinel 项目集成实践

目录

一、简介

SentinelSpringCloud Alibaba 家族的服务保护组件,很多项目在前中期没有遇到流量突增不太注意服务保护的重要性,当流量突增打爆应用服务或数据库时束手无策,可以不配置流控规则,但是需要时一定可以热加载使用,本文会对集成Sentinel以及动态拉取Nacos配置规则实现热加载流控规则进行讲解。

官网地址

1.1、服务保护的基本概念

1.1.1、服务限流/熔断
  • 服务限流目的是为了更好的保护我们的服务,在高并发的情况下,如果客户端请求的数量达到一定极限(后台可以配置阈值),请求的数量超出了设置的阈值,开启自我的保护,直接调用我们的服务降级的方法,不会执行业务逻辑操作,直接走本地falback的方法,返回一个友好的提示。
1.1.2、服务降级
  • 在高并发的情况下, 防止用户一直等待,采用限流/熔断方法,使用服务降级的方式返回一个友好的提示给客户端,不会执行业务逻辑请求,直接走本地的falback的方法。
    给出一个友好提示:当前排队人数过多,稍后重试!
1.1.3、服务的雪崩效应
  • 默认的情况下,Tomcat或者是Jetty服务器只有一个线程池去处理客户端的请求,
    这样的话就是在高并发的情况下,如果客户端所有的请求都堆积到同一个服务接口上,
    那么就会产生tomcat服务器所有的线程都在处理该接口,可能会导致其他的接口无法访问。
    假设我们的tomcat线程最大的线程数量是为20,这时候客户端如果同时发送100个请求会导致有80个请求暂时无法访问,就会转圈。
1.1.4、服务的隔离的机制
  • 服务的隔离机制分为信号量和线程池隔离模式
    服务的线程池隔离机制:每个服务接口都有自己独立的线程池,互不影响,缺点就是占用cpu资源非常大。
    服务的信号量隔离机制:最多只有一定的阈值线程数处理我们的请求,超过该阈值会拒绝请求。

1.2、Sentinel的主要特性

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

1.3、Sentinel整体架构

有特殊需要还可以将自定义规则插入调用链路中。

1.4、Sentinel 与 Hystrix 对比

Sentinel Hystrix
隔离策略 信号量隔离 线程池隔离/信号量隔离
熔断降级策略 基于响应时间或失败比率 基于失败比率
实时指标实现 滑动窗口 滑动窗口(基于 RxJava)
规则配置 支持多种数据源 支持多种数据源
扩展性 多个扩展点 插件的形式
基于注解的支持 支持 支持
限流 基于 QPS,支持基于调用关系的限流 有限的支持
流量整形 支持慢启动、匀速器模式 不支持
系统负载保护 支持 不支持
控制台 开箱即用,可配置规则、查看秒级监控、机器发现等 不完善
常见框架的适配 Servlet、Spring Cloud、Dubbo、gRPC 等 Servlet、Spring Cloud Netflix

二、Sentinel控制台部署

3.1、版本选择和适配

使用 SpringCloud Alibaba 家族组件,要注意一下版本兼容问题,避免出现一些奇怪的问题,这里会说明本文使用的各组件版本,以及 SpringCloud Alibaba 推荐的各版本适配。

3.2、本文使用各组件版本

部分组件对版本兼容要求其实没有那么高,比如Nacos,不一定要按照官方推荐版本,差几个小版本没有什么影响,我本地使用的一直是Nacos2.0.2,代码集成实现基本都一样。

JDK:1.8.0

Spring-Boot:2.3.12.RELEASE

Spring-Cloud:Hoxton.SR12

Spring-Cloud-Alibaba:2.2.9.RELEASE

Nacos:2.0.2

Sentinel:1.8.5

3.3、官方推荐版本

官方版本说明

3.4、部署Sentinel控制台

3.4.1、下载 sentinel-dashboard jar包

这里使用sentinel-dashboard-1.8.5,这里提供两个下载地址,需要其它版本可以自行去github下载,如果有条件建议直接下载sentinel-dashboard源码部署,后续需要对sentinel-dashboard源码进行改造才能进行流控规则双向同步。。
github下载地址
百度网盘地址

3.4.2、启动 sentinel-dashboard
bash 复制代码
java -Dserver.port=8180 -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.5.jar
  • -Dserver.port=8180
    sentine 服务控制台端口
  • -Dsentinel.dashboard.auth.username=sentinel
    sentine 控制台登录账号,不设置默认sentinel
  • -Dsentinel.dashboard.auth.password=123456
    sentine 控制台登录密码,不设置默认sentinel
  • -Dcsp.sentinel.dashboard.server=localhost:8180
    将控制台自身注册到server
  • -Dproject.name=sentinel-dashboard
    控制台服务自己项目名称


三、项目集成 Sentinel 实现简单流控

3.1、项目中添加 Sentinel 集成包

xml 复制代码
		<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

3.2、简单集成(不使用Sentinel控制台配置)

3.2.1、添加流控规则

流控规则是由FlowRuleManager类统一管理的,只要将规则编辑好加载到FlowRuleManager类中即可,也可以使用一个接口来添加,添加前先获取已有规则然后追加,比较简单这里不过多说明。

java 复制代码
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Configuration
public class SentinelRuleInitConfiguration {
    public final static String GETUSER_KEY = "getUserInfo";

    @PostConstruct
    public void initSentinelRule() {
        // 先从FlowRuleManager获取已有规则
        List<FlowRule> rules = FlowRuleManager.getRules();
        // 判断FlowRuleManager中是否存在规则,如果不存在则新建一个ArrayList用于存放
        rules = rules != null ? rules : new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        // 设置资源名称
        rule1.setResource(GETUSER_KEY);
        // QPS控制在1以内
        rule1.setCount(1);
        // QPS限流
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("default");
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
        log.info(">>>限流服务接口配置加载成功>>>");
    }
}
3.2.2、使用 3.2.1 加载的流控规则
3.2.2.1、硬编码使用流控规则
java 复制代码
    @GetMapping("/user/info-01")
    public String getUserInfo01(){
        Entry entry = null;
        try {
        	// 指定 3.2.1 中的资源名称
            entry = SphU.entry(SentinelRuleInitConfiguration.GETUSER_KEY);
            // 执行我们服务需要保护的业务逻辑
            return "张三" + RandomUtil.randomNumbers(5);
        } catch (Exception e) {
            e.printStackTrace();
            return "该服务接口已经达QPS上线!";
        } finally {
            // SphU.entry(xxx) 需要与 entry.exit() 成对出现,否则会导致调用链记录异常
            if (entry != null) {
                entry.exit();
            }
        }
    }

在浏览器快速调用几次就能看到触发限流规则响应指定信息。

3.2.2.2、使用@SentinelResource指定流控规则
java 复制代码
    //@SentinelResource  value参数:流量规则资源名称、
    //blockHandler 限流/熔断出现异常执行的方法
    //Fallback 服务的降级执行的方法
    @SentinelResource(value = SentinelRuleInitConfiguration.GETUSER_KEY, blockHandler = "getUserInfoQpsException")
    @GetMapping("/user/info-02")
    public String getUserInfo02(){
        return "张三" + RandomUtil.randomNumbers(5);
    }

    /**
     * 被限流后返回的提示
     */
    public String getUserInfoQpsException(BlockException e) {
        e.printStackTrace();
        return "该接口已经被限流啦!";
    }

使用注解也是一样的,只是触发限流规则后会走我们指定的blockHandler

3.3、集成 Sentinel 控制台实现流控规则动态配置

3.3.1、添加Sentinel控制台连接配置
yaml 复制代码
spring:
  application:
    name: kerwin-user
  cloud:
    sentinel:
      # 设置sentinel为热加载 默认为false
      eager: true
      # 配置Sentinel控制台连接信息 建议通过启动参数配置
      transport:
        # 控制台ip:端口
        dashboard: localhost:8180
        # 应用注册端口 默认8719
        port: 18819

PS:要是通过配置文件配置无法注册到 Sentinel控制台,可以通过JVM启动参数配置试一下

-Dcsp.sentinel.dashboard.server=127.0.0.1:8180

-Dcsp.sentinel.api.port=18819

-Dproject.name=kerwin-user

  • 参数说明:
    -Dcsp.sentinel.dashboard.server:指定控制台地址和端口。
    -Dproject.name:在sentinel控制台中展示的项目名称。
    -Dcsp.sentinel.api.port:指定客户端监控 API 的端口(默认是 8719),如控制台修改规则,则会向该端口推送规则信息。

注册成功后可以看到多了一个kerwin-user,并且之前配置的流控规则也被加载到控制台。

3.3.2、通过控制台添加新流控规则测试效果
3.3.2.1、先准备一个接口(这个接口只简单返回一个字符串)
java 复制代码
    @GetMapping("/user/info-03")
    public String getUserInfo03(){
        return "李四" + RandomUtil.randomNumbers(5);
    }
3.3.2.2、控制台添加流控规则

除了通过@SentinelResource指定接口使用的资源名称,还可以将资源名设置成接口完整地址是会被自动匹配的,在spring-cloud-starter-alibaba-sentinel包中已经做了适配。

3.3.2.3、测试流控效果

快速请求几次可以看到触发了流控,响应了Sentinel的默认流控提示信息,这个响应信息可以做统一处理,文章末尾提供实现代码。

四、项目整合 Nacos 实现 Sentinel 规则持久化

  • 因为Sentinel客户端是将规则数据存储在本地JVM中,Sentinel控制台会读取客户端的规则到控制台显示,Sentinel控制台只做规则读取和规则配置并不会做数据的存储,规则修改之后Sentinel会将规则PUSH到客户端,当客户端重启以后新增规则也会消失 ,如果Sentinel控制台重启客户端没有重启这个时候Sentinel控制台又能将客户端缓存中的规则和族点链路信息读取到控制台。
    • 解决方法一:修改Sentinel客户端源码在新增和修改规则时将数据重新储存到数据库或者本地文件,当客户端宕机重启后Sentinel控制台根据客户端唯一标识取出对应数据push到客户端。
    • 解决方法二:集成Nacos等工具,将规则信息储存在配置中心,在客户端项目启动时去读取,也可以随时修改可以做到动态更新,但是做不到Sentinel控制台修改规则然后同步到nacos配置中心。

4.1、添加 Sentinel 集成 Nacos 包

sentinel读取nacos配置需要添加这个适配包。

xml 复制代码
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

4.2、Nacos配置中心创建我们的流控规则(kerwin-user-flow-rules)


规则JSON

yaml 复制代码
[
    {
        "resource": "/user/info-03",
        "limitApp": "default",
        "grade": 1,
        "count": 2,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]
  • 各字段含义
    • resource:这是流控规则所针对的资源名称,你要依据实际业务情况对其进行替换。
    • limitApp:指定受此规则限制的调用来源,default 表示对所有调用来源都生效。
    • grade:流控阈值类型,1 代表 QPS(每秒查询率),0 代表线程数。
    • count:设定的流控阈值。在上述例子中,QPS 的阈值为 2,即每秒请求数量超过 2 时就会触发流控。
    • strategy:流控策略,0 表示直接对当前资源进行限流。
    • controlBehavior:流控效果,0 代表快速失败,也就是请求超过阈值时直接拒绝。
    • clusterMode:是否为集群流控模式,false 表示使用单机流控模式。

4.3、配置文件配置加载Nacos配置中心流控规则json

yaml 复制代码
spring:
  cloud:
    sentinel:
      # 设置sentinel为热加载 默认为false
      eager: true
      # 使用nacos来做持久化
      datasource:
        ## 配置流控规则,名字任意
        ds-flow:
          nacos:
            ## nacos的地址
            server-addr: 172.16.8.169:8848
            ## 配置ID
            dataId: kerwin-user-flow-rules
            username: nacos
            password: nacos
            namespace: springcloud-component-example
            ## 配置分组,默认是DEFAULT_GROUP
            groupId: DEFAULT_GROUP
            ## 配置存储的格式
            data-type: json
            ## rule-type设置对应得规则类型,总共七大类型,在com.alibaba.cloud.sentinel.datasource.RuleType这个枚举类中有体现
            rule-type: flow

4.4、验证配置是否有效

重启应用服务查看 Sentinel控制台 Nacos中配置的规则是否注册上,如果成功可以看到刚刚配置的规则已经加载到流控规则中,但是之前我们通过代码配置的流控规则没了,这是因为Sentinel加载Nacos中配置规则在我们通过代码配置之后,通过代码配置的规则被覆盖了,不过线上环境也不推荐使用代码直接配置,还是统一使用配置中心比较合适。

五、常用规则配置JSON解析以及加载

这里会对所有服务保护规则JSON配置参数做解析,将对应规则配置到Nacos配置中心,在配置文件中指定规则加载即可。

5.1、流量控制规则(FlowRule)

5.1.1、配置流控规则JSON
  • Nacos配置中心添加流控规则kerwin-user-flow-rules

  • 规则JSON

    yaml 复制代码
    [
        {
            "resource": "youResource",
            "limitApp": "default",
            "grade": 1,
            "count": 10,
            "strategy": 0,
            "controlBehavior": 0,
            "clusterMode": false
        }
    ]
  • 字段解释:

    • resource:此为流控规则所针对的资源名称,代表了系统里某个具体的功能或者服务,像某个接口的调用。
    • limitApp:指定受该规则限制的调用来源。default 意味着对所有调用来源都生效;也可以填入具体的应用名,实现对特定调用来源的限流。
    • grade:流控阈值类型,具体取值如下:
      • 0:代表线程数限流,即当并发线程数超过阈值时触发限流。
      • 1:代表 QPS(每秒查询率)限流,即当每秒的请求数超过阈值时触发限流。
    • count:流控阈值,其含义由 grade 字段决定。若 grade 为 0,它就是最大并发线程数;若 grade 为 1,它就是每秒允许的最大请求数。
    • clusterMode:是否为集群流控模式。false 表示单机流控模式;true 表示集群流控模式。
    • strategy:流控策略,具体取值如下:
      • 0:直接对当前资源进行限流。
      • 1:关联资源限流,当关联资源的 QPS 超过设置的阈值时,对当前资源进行限流。
      • 2:链路限流,是指只对指定链路的请求进行限流。在复杂的系统中,一个资源可能会被多个不同的链路调用,链路流控可以针对特定的调用链路进行流量控制,而不影响其他链路对该资源的访问。。
    • refResource:关联或入口资源名,当strategy 为 2或3时有效,
    • controlBehavior:流控效果,具体取值如下:
      • 0:快速失败,当请求超过阈值时,直接拒绝请求并抛出限流异常。
      • 1:Warm Up(预热),让系统有一个预热的过程,避免瞬间流量过大。
      • 2:匀速排队,请求会进入队列进行排队,按照固定的速率处理请求。
      • 3:Warm Up + 匀速排队,结合了预热和匀速排队的特性。
    • warmUpPeriodSec:仅在 controlBehavior 为 1(Warm Up)或者 3(Warm Up + 匀速排队)时有效,代表预热的时长,单位是秒。
    • maxQueueingTimeMs:仅在 controlBehavior 为 2(匀速排队)或者 3(Warm Up + 匀速排队)时有效,代表请求在队列中的最大排队时间,单位是毫秒。若排队时间超过该值,请求将被拒绝。
    • slowRatioThreshold:仅在 controlBehavior 为 2(匀速排队)或者 3(Warm Up + 匀速排队)时有效,代表慢调用比例阈值。当慢调用(处理时间超过某个阈值的请求)的比例超过该阈值时,会调整排队的速率。
5.1.2、配置文件配置加载Nacos配置中心流控规则json
yaml 复制代码
spring:
  cloud:
    sentinel:
      # 设置sentinel为热加载 默认为false
      eager: true
      # 使用nacos来做持久化
      datasource:
        ## 配置规则,名字任意
        ds-flow:
          nacos:
            ## nacos的地址
            server-addr: 172.16.8.169:8848
            ## 配置ID
            dataId: kerwin-user-flow-rules
            username: nacos
            password: nacos
            namespace: springcloud-component-example
            ## 配置分组,默认是DEFAULT_GROUP
            groupId: DEFAULT_GROUP
            ## 配置存储的格式
            data-type: json
            ## rule-type设置对应得规则类型,总共七大类型,在com.alibaba.cloud.sentinel.datasource.RuleType这个枚举类中有体现
            ## flow:流控 degrade:熔断降级  param-flow:热点参数规则  system:系统保护规则  authority:授权规则
            rule-type: flow

5.2、熔断降级规则(DegradeRule)

5.2.1、配置熔断降级规则JSON
  • Nacos配置中心添加流控规则kerwin-user-degrade-rules
  • 规则JSON
yaml 复制代码
[
    {
        "resource": "youResource",
        "count": 0.5,
        "timeWindow": 10,
        "grade": 0,
        "minRequestAmount": 5,
        "statIntervalMs": 10000,
        "slowRatioThreshold": 0.5,
        "maxAllowedRt": 200
    }
]
  • 字段解释:
    • resource:要进行熔断降级控制的资源名称,代表了系统中的某个特定功能或服务,例如某个接口的调用。
    • count:熔断阈值,具体含义根据 grade 字段的值而定。
      • 当 grade 为 0(错误比例策略)时,count 表示错误请求数占总请求数的比例阈值,范围是 0.0 - 1.0。例如,值为 0.5 表示错误比例达到 50% 时触发熔断。
      • 当 grade 为 1(平均响应时间策略)时,count 表示平均响应时间的阈值(单位:毫秒)。例如,值为 200 表示平均响应时间超过 200 毫秒时触发熔断。
      • 当 grade 为 2(异常数策略)时,count 表示异常请求数的阈值。
        timeWindow:熔断的时长,单位为秒。例如,值为 10 表示熔断持续 10 秒,在这期间对该资源的请求会被直接熔断处理。
    • grade:降级策略,有以下几种取值:
      • 0:错误比例策略,根据错误请求数占总请求数的比例来判断是否熔断。
      • 1:平均响应时间策略,根据请求的平均响应时间来判断是否熔断。
      • 2:异常数策略,根据异常请求数来判断是否熔断。
    • minRequestAmount:最小请求数,只有在统计周期内的请求数达到该值时,才会进行熔断判断。例如,设置为 5 表示当请求数至少为 5 时,才会根据 count 和 grade 的规则判断是否熔断。
    • statIntervalMs:统计时长,单位为毫秒,用于统计错误比例、平均响应时间或异常数。例如,值为 10000 表示统计最近 10 秒内的数据。
    • slowRatioThreshold:慢调用比例阈值,仅在平均响应时间策略(grade 为 1)下有效。它表示慢调用(响应时间超过 maxAllowedRt)在总请求数中的占比阈值,范围是 0.0 - 1.0。例如,值为 0.5 表示慢调用比例达到 50% 时触发熔断。
    • maxAllowedRt:最大允许的响应时间,仅在平均响应时间策略(grade 为 1)下有效。当请求的响应时间超过该值时,该请求会被视为慢调用。
5.2.2、配置文件配置加载Nacos配置中心熔断降级规则json
yaml 复制代码
spring:
  cloud:
    sentinel:
      # 设置sentinel为热加载 默认为false
      eager: true
      # 使用nacos来做持久化
      datasource:
        ds-flow:
          nacos:
            server-addr: 172.16.8.169:8848
            dataId: kerwin-user-flow-rules
            username: nacos
            password: nacos
            namespace: springcloud-component-example
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
        ## 配置熔断降级规则,名字任意
        ds-degrade:
          nacos:
            ## nacos的地址
            server-addr: 172.16.8.169:8848
            ## 配置ID
            dataId: kerwin-user-degrade-rules
            username: nacos
            password: nacos
            namespace: springcloud-component-example
            ## 配置分组,默认是DEFAULT_GROUP
            groupId: DEFAULT_GROUP
            ## 配置存储的格式
            data-type: json
            ## rule-type设置对应得规则类型,总共七大类型,在com.alibaba.cloud.sentinel.datasource.RuleType这个枚举类中有体现
            ## flow:流控 degrade:熔断降级  param-flow:热点参数规则  system:系统保护规则  authority:授权规则
            rule-type: degrade

5.3、热点参数规则(ParamFlowRule)

5.3.1、配置熔断降级规则JSON
  • Nacos配置中心添加流控规则kerwin-user-param-flow-rules

  • 规则JSON

    yaml 复制代码
    [
        {
            "resource": "youResource",
            "count": 5,
            "grade": 1,
            "paramIdx": 0,
            "durationInSec": 1,
            "controlBehavior": 0,
            "clusterMode": false,
            "clusterConfig": {
                "thresholdType": 1,
                "fallbackToLocalWhenFail": true
            },
            "paramFlowItemList": [
                {
                	"classType": "java.lang.String",
                    "object": "paramValue",
                    "count": 10
                }
            ]
        }
    ]
  • 字段解释:

    • resource:要进行热点参数流控的资源名称,代表系统中的某个特定功能或接口。
    • count:针对普通参数值的流控阈值。当参数不是 paramFlowItemList 中指定的特殊值时,使用该阈值进行流控。
    • grade:流控阈值类型,1:表示基于 QPS(每秒查询率)进行流控。
    • paramIdx:参数索引,指定要对方法参数列表中哪个位置的参数进行热点流控。索引从 0 开始,例如 0 表示第一个参数。
    • durationInSec:统计时长,单位为秒。Sentinel 会在这个时间段内统计参数的访问情况,以判断是否触发流控。
    • controlBehavior:流控效果,取值如下:
      • 0:快速失败,当请求超过阈值时直接拒绝请求。
      • 1:Warm Up(预热),系统启动初期允许较低的流量,随着时间推移逐渐增加到正常阈值。
      • 2:匀速排队,请求会进入队列,按照固定速率处理,避免流量突发。
    • clusterMode:是否为集群流控模式。true 表示开启集群流控,false 表示使用单机流控。
    • clusterConfig:集群流控的相关配置,是一个对象,包含以下字段:
      • thresholdType:集群阈值类型,0 表示全局阈值,即整个集群共享一个阈值;1 表示单机均摊阈值,每个节点有自己的阈值。
      • fallbackToLocalWhenFail:当集群流控失败时,是否回退到单机流控模式,true 表示回退,false 表示不回退。
    • paramFlowItemList:针对特定参数值的流控规则列表,是一个数组,数组中的每个对象包含以下字段:
      • classType:参数类型 int、double、java.lang.String、long、float、char、byte
      • object:特定的参数值。
      • count:针对该特定参数值的流控阈值,会覆盖普通参数的 count 阈值。
5.3.2、配置文件配置加载Nacos配置中心熔断降级规则json
yaml 复制代码
spring:
  cloud:
    sentinel:
      # 设置sentinel为热加载 默认为false
      eager: true
      # 使用nacos来做持久化
      datasource:
        ## 配置规则,名字任意
        ds-param-flow:
          nacos:
            ## nacos的地址
            server-addr: 172.16.8.169:8848
            ## 配置ID
            dataId: kerwin-user-param-flow-rules
            username: nacos
            password: nacos
            namespace: springcloud-component-example
            ## 配置分组,默认是DEFAULT_GROUP
            groupId: DEFAULT_GROUP
            ## 配置存储的格式
            data-type: json
            ## rule-type设置对应得规则类型,总共七大类型,在com.alibaba.cloud.sentinel.datasource.RuleType这个枚举类中有体现
            ## flow:流控 degrade:熔断降级  param-flow:热点参数规则  system:系统保护规则  authority:授权规则
            rule-type: param-flow

5.4、系统保护规则(SystemRule)

5.4.1、配置熔断降级规则JSON
  • Nacos配置中心添加流控规则kerwin-user-system-rules
  • 规则JSON
yaml 复制代码
[
    {
        "highestCpuUsage": -1,
        "avgRt": -1,
        "maxThread": -1,
        "qps": 10,
        "highestSystemLoad": -1
    }
]
  • 字段解释:
    • highestCpuUsage:最大 CPU 使用率,超过该值时触发系统保护。
    • avgRt:平均响应时间,超过该值时触发系统保护。
    • maxThread:最大线程数,超过该值时触发系统保护。
    • qps:最大 QPS,超过该值时触发系统保护。
    • highestSystemLoad:最大系统负载,超过该值时触发系统保护。
5.4.2、配置文件配置加载Nacos配置中心熔断降级规则json
yaml 复制代码
spring:
  cloud:
    sentinel:
      # 设置sentinel为热加载 默认为false
      eager: true
      # 使用nacos来做持久化
      datasource:
        ## 配置规则,名字任意
        ds-system:
          nacos:
            ## nacos的地址
            server-addr: 172.16.8.169:8848
            ## 配置ID
            dataId: kerwin-user-system-rules
            username: nacos
            password: nacos
            namespace: springcloud-component-example
            ## 配置分组,默认是DEFAULT_GROUP
            groupId: DEFAULT_GROUP
            ## 配置存储的格式
            data-type: json
            ## rule-type设置对应得规则类型,总共七大类型,在com.alibaba.cloud.sentinel.datasource.RuleType这个枚举类中有体现
            ## flow:流控 degrade:熔断降级  param-flow:热点参数规则  system:系统保护规则  authority:授权规则
            rule-type: system

六、Sentinel 规则触发响应信息统一处理

java 复制代码
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws Exception {
        String msg = "触发服务保护!";
        if (ex instanceof FlowException) {
            msg = "请求过于频繁,被限流了!";
        } else if (ex instanceof DegradeException) {
            msg = "请求过于频繁,被降级了!";
        } else if (ex instanceof ParamFlowException) {
            msg = "热点数据请求过于频繁!";
        } else if (ex instanceof SystemBlockException) {
            msg = "请求过于频繁,触发系统限制!";
        } else if (ex instanceof AuthorityException) {
            msg = "授权规则不通过!";
        }
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        response.setContentType("application/json;charset=utf-8");
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("code",500);
        resultMap.put("msg",msg);
        String errJson = JSON.toJSONString(resultMap);
        new ObjectMapper().writeValue(response.getWriter(), errJson);
    }
}

触发流控规则后调用了SentinelExceptionHandler 中的handle响应了我们自定义的异常信息。

相关推荐
ChinaRainbowSea13 分钟前
三. Redis 基本指令(Redis 快速入门-03)
java·数据库·redis·缓存·bootstrap·nosql
DEARM LINER14 分钟前
RabbitMQ 分布式高可用
java·spring boot·分布式·rabbitmq
weisian15120 分钟前
消息队列篇--扩展篇--码表及编码解码(理解字符字节和二进制,了解ASCII和Unicode,了解UTF-8和UTF-16,了解字符和二进制等具体转化过程等)
java·开发语言
呦呦鹿鸣Rzh28 分钟前
实现标题-超链接
java·前端·javascript
Bug退退退12335 分钟前
JVM常见知识点
java·jvm
fly spider1 小时前
每日 Java 面试题分享【第 13 天】
java·开发语言·面试
大名顶顶1 小时前
【JAVA实战】如何使用 Apache POI 在 Java 中写入 Excel 文件
java·spring boot·后端·计算机·程序员·编程·软件开发
gentle_ice2 小时前
leetcode——矩阵置零(java)
java·算法·leetcode·矩阵
whisperrr.3 小时前
【JavaWeb06】Tomcat基础入门:架构理解与基本配置指南
java·架构·tomcat