实用指南:Sentinel

微服务学习顺序:
微服务之Nacos
微服务之OpenFeign
微服务之网关
微服务之Sentinel

Sentinel 介绍

在基于 SpringCloud 构建的微服务体系中,服务间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素。在并发流量比较高的情况下,由于网络调用之间存在一定的超时时间,链路中的某个服务出现宕机都会大大增加整个调用链路的响应时间,而瞬间的流量洪峰则会导致这条链路上所有服务的可用线程资源被打满,从而造成整体服务的不可用,这也就是我们常说的 “雪崩效应”。而在微服务系统设计的过程中,为了应对这样的糟糕情况,最常用的手段就是进行 ”流量控制“ 以及对网络服务的调用实现“熔断降级”。因此,Sentinel 就因运而生了。

Sentinel 是一款面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来保障服务的稳定性,核心思想是:根据对应资源配置的规则来为资源执行相应的流控/降级/系统保护策略。

Sentinel 的历史

  • 2012 年,Sentinel 诞生,主要功能为入口流量控制。
  • 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
  • 2018 年,Sentinel 开源,并持续演进。
  • 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。
  • 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。
  • 2021 年,Sentinel 正在朝着 2.0 云原生高可用决策中心组件进行演进;同时推出了 Sentinel Rust 原生版本。同时我们也在 Rust 社区进行了 Envoy WASM extension 及 eBPF extension 等场景探索。
  • 2022 年,Sentinel 品牌升级为流量治理,领域涵盖流量路由/调度、流量染色、流控降级、过载保护/实例摘除等;同时社区将流量治理相关标准抽出到 OpenSergo 标准中,Sentinel 作为流量治理标准实现。

Sentinel 基本概念

资源

资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务(api接口请求路径),甚至可以是一段代码。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

规则

围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

Sentinel 功能和设计理念

流量控制

其原理是监控应用流量的 QPS(每秒请求次数) 或并发线程数(即同一时间发起请求的用户数量)等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
在这里插入图片描述

熔断降级

什么是熔断降级

除了流量控制以外,降低调用链路中的不稳定资源也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积。这个问题和 Hystrix 里面描述的问题是一样的。
在这里插入图片描述
Sentinel 和 Hystrix 的原则是一致的:当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。

熔断降级设计理念

在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。

Hystrix 通过线程池的方式,来对依赖(在我们的概念中对应资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本,还需要预先给各个资源做线程池大小的分配。

Sentinel 对这个问题采取了两种手段:

  • 通过并发线程数(可看成一个用户就是一个线程)进行限制
    和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
  • 通过响应时间对资源进行降级
    除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。

系统负载保护

Sentinel 同时提供系统维度的自适应保护能力。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。

针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。

Sentinel 是如何工作的

Sentinel 的主要工作机制如下:

  • 对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。
  • 根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便您定义及改变规则。
  • Sentinel 提供实时的监控系统,方便您快速了解目前系统的状态。

快速开始

Sentinel 的使用可以分为两个部分:

  • 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard):Dashboard(就是可视化界面)主要负责管理推送规则、监控、管理机器信息等。

Sentinel 控制台

sentinel官网:https://sentinelguard.io/zh-cn/

下载sentinel-dashboard-1.8.9.jar

使用以下命令直接运行 jar 包(JDK 版本必须≥ 1.8):

java -jar -Dserver.port=9999 sentinel-dashboard-1.8.9.jar

控制台访问地址:http://localhost:9999。默认账号密码都为:sentinel
在这里插入图片描述

Sentinel 采用 “懒加载” 机制:只有当业务服务的接口被实际调用后,控制台才会显示该服务的信息。

Sentinel 控制台启动后默认没有任何信息,是因为业务服务尚未与控制台建立连接。需要通过配置让你的业务服务 “连接” 到控制台,控制台才能获取到服务的监控数据和规则配置。

SpringBoot 整合 sentinel-dashboard

这里基于我的另一篇文章的微服务项目基础上进行实现:微服务之网关

基本搭建:

  1. 在子项目provider-7790的pom文件引入核心库依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  1. 在provider-7790项目的application.yml编写代码,在业务服务的配置文件中添加控制台地址
server:
port: 7790
spring:
application:
name: provider-7790 #往注册中心放的服务名称,一般与项目名保持一致(服务名称不能重复)
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8850
username: nacos
password: nacos
sentinel:
transport:
dashboard: 127.0.0.1:9999 #连接Sentinel控制台dashboard的信息
port: 8719 #TCP协议 与dashboard通信的端口(默认8719)
enabled: true #开启sentinel 默认true
eager: true #取消控制台懒加载 立即初始化dashboard与sentinel
feign:
circuitbreaker:
enabled: true # 开启熔断处理
  1. 启动provider-7790、bill-7780(注意还要先启动nacos),刷新Sentinel控制台页面。

我们要后面要调用的provider-7790的接口方法内部会去调用bill-7780对外提供的接口方法。

在这里插入图片描述

浏览器请求路径:http://localhost:7790/bill/listByProId?id=1
在这里插入图片描述

查看Sentinel控制台的事实监控(反应会有点慢,需要稍微等一下)
在这里插入图片描述

流量控制:

Sentinel 流量控制的核心作用是防止系统因突发流量或异常请求被打垮,核心用在 “流量可能超出系统承载能力” 的场景。
比如:促销活动期间,提前设定接口 QPS 上限(如 1000),当流量突增到阈值时,直接拦截超出部分请求(返回限流提示),避免数据库、服务器资源被耗尽,保证系统核心功能可用。

一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果:

  • resource :资源名,即限流规则的作用对象 (访问路径)
  • count : 限流阈值(最大接受数,超过阈值拒绝访问)
  • grade : 限流阈值类型(QPS 或并发线程数)
  • limitApp : 流控针对的调用来源,若为 default 则不区分调用来源(那个服务调用资源名时进行限流,default不区分)
  • strategy : 调用关系限流策略
  • controlBehavior : 流量控制效果(直接拒绝、Warm Up、匀速排队)

我们这里设置每秒钟只能成功访问http://localhost:7790/bill/listByProId?id=1一次
在这里插入图片描述
在这里插入图片描述
运行测试:我们会发现当每秒发送多次请求时,系统报错
在这里插入图片描述
在这里插入图片描述
这里配置的流量控制规则不是持久化的,重启Sentinel后就没了,我们后面会学习通过nacos的配置中心进行持久化存储流控规则。

注意:除了设置QPS外,也可以设置线程数。(可让业务代码进行休眠,或使用压力测试工具就jmeter)

当设置线程数为1时,可以用jmeter测试,5个线程同一时刻发送。
在这里插入图片描述
在这里插入图片描述

流控模式与流控效果:

在这里插入图片描述

关联:(反向关联)

在 Sentinel 的关联模式限流规则中,其核心逻辑是当关联的资源达到限流阈值时,对当前资源进行限流,以此实现资源之间的关联限流控制,常用于解决资源之间的竞争问题(如读和写操作竞争同一资源时,限制读操作以保障写操作的稳定性)

在子项目provider-7790的controller中再复制一个listByProId方法,改名为listByProId1

package com.lp.controller;
import com.lp.service.api.SmbmsBillService;
import com.lp.utils.ResultAJAX;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/bill")
public class SmbmsBillController {
@Autowired
private SmbmsBillService smbmsBillService;
@GetMapping("/listByProId")
public ResultAJAX listByProId(Integer id){
return smbmsBillService.listByProId(id);
}
@GetMapping("/listByProId1")
public ResultAJAX listByProId1(Integer id){
return smbmsBillService.listByProId(id);
}
}

在这里插入图片描述

注意:在关联模式下,这里的“单机阈值” 是关联资源的阈值,而非当前资源的阈值。当关联资源的流量(每秒请求数量)达到这个阈值时,才会对当前资源进行限流。

/bill/listByProId的阈值超过到1时,/bill/listByProId1不可用。(把/bill/listByProId1的资源节省出来给/bill/listByProId

在同一台电脑上测试,浏览器先访问/bill/listByProId,同时再快速访问/bill/listByProId1(手速要快,保证在1秒内按顺序访问)
在这里插入图片描述
结果,浏览器访问/bill/listByProId1被限流
在这里插入图片描述

快速失败:抛异常

方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出 FlowException 。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。

WarmUp:慢慢增加到阈值

即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

即预热模式会先以一个较低的初始阈值允许请求通过,然后在 “预热时长” 内逐渐提升到配置的 “单机阈值”,使系统资源逐步被利用,最终稳定在目标承载能力上。

修改流控配置为如下:
在这里插入图片描述
保存,浏览器连续访问http://localhost:7790/bill/listByProId1?id=1
在这里插入图片描述
会发现刚开始会断断续续被限流,到后面阈值增加到5后,请求就趋于稳定了。

排队等待:匀速排队处理

方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法 。
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
注意:匀速排队模式暂时不支持 QPS > 1000 的场景。

当流量超过阈值时,Sentinel 会将超出的请求放入队列中匀速处理,而不是直接拒绝(如 “快速失败” 模式)。这样可以在保障系统稳定的前提下,尽可能处理更多请求,适用于对延迟不敏感但要求流量平稳的场景(如消息队列消费、批量数据处理等)。

注意:超时时间是对单个请求在队列中允许等待的最大时长限制,而非所有队列请求的总超时时间。

修改流控配置为如下:
在这里插入图片描述
浏览器访问http://localhost:7790/bill/listByProId1?id=1进行测试。

熔断降级:

现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。

Sentinel 熔断规则的生效,和异常在 “当前服务(provider-7790)” 还是 “下游服务(bill-7780)” 无关,只和 “异常是否被 Sentinel 统计为资源的调用异常” 有关。只要是 Sentinel 监控的 “资源” 在调用时抛出了异常,不管异常来自当前服务还是下游服务,都会触发该资源的熔断规则。

添加熔断规则
在这里插入图片描述

慢调用比例 ( SLOW_REQUEST_RATIO )

在 Sentinel 的慢调用比例熔断策略中,其核心是通过统计资源的慢调用情况,当慢调用比例达到阈值时,触发熔断,暂时阻止对该资源的请求,避免因资源响应慢导致整个系统雪崩。

选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。
当统计时长(周期)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来在的熔断时长内的请求会自动被熔断。
熔断时长结束后,进入 “半开(HALF-OPEN)” 状态:允许一个请求尝试访问资源,若该请求正常(非慢调用),则熔断关闭,恢复正常;若仍为慢调用,则再次被熔断。

参数含义&作用
最大RT定义 “慢调用” 的阈值,单位为秒。表示超过最大RT(最大的响应时间)的调用会被标记为慢调用。
比例阈值慢调用占总调用的比例阈值,范围 0~1。(如:设置为0.2,如果慢调用数超过2%则进入熔断降级)
熔断时长熔断后的持续时间,单位为秒。表示熔断触发后,指定时间内对该资源的请求会被直接拒绝。
最小请求数统计周期内的最小请求数量。只有当统计周期内的请求数≥最小请求数 时,才会触发熔断判断。请求数小于该值时即使慢调用比率超出阈值也不会熔断
统计时长(周期)统计数据的时间窗口,单位为毫秒。图中设置为1000(即 1 秒),表示每 1 秒统计一次该资源的调用情况。

浏览器访问http://localhost:7790/bill/listByProId?id=1进行测试

异常比例 ( ERROR_RATIO )

当单位统计时长( statIntervalMs )内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0] ,代表 0% - 100%。

异常数 ( ERROR_COUNT )

当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

修改provider-7790服务的控制器类,使用@SentinelResource注解

package com.lp.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.lp.service.api.SmbmsBillService;
import com.lp.utils.ResultAJAX;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/bill")
public class SmbmsBillController {
@Autowired
private SmbmsBillService smbmsBillService;
@GetMapping("/listByProId")
@SentinelResource(value="byId", blockHandler="defaultFallback")
public ResultAJAX listByProId(Integer id){
if(id==3){
int i =1/0;
//            throw new RuntimeException("服务异常");
}
return smbmsBillService.listByProId(id);
}
// 熔断时的处理方法(返回非500的响应,如自定义提示)
public ResultAJAX defaultFallback(Integer id, BlockException e) {
return ResultAJAX.success("服务熔断中,请稍后再试");
}
@GetMapping("/listByProId1")
public ResultAJAX listByProId1(Integer id){
return smbmsBillService.listByProId(id);
}
}

熔断规则,异常数策略
在这里插入图片描述
浏览器访问http://localhost:7790/bill/listByProId?id=3
在这里插入图片描述

熔断规则生效的两种场景

  • 无注解场景:Sentinel 会自动将 HTTP 接口的 URL 作为 “资源名”(如 /bill/listByProId),对该 URL 的请求会被自动监控。此时配置熔断规则时,资源名填写 URL 即可生效(无需注解)。资源名固定为 URL,且熔断 / 限流时会直接抛出异常(如 DegradeException),需手动全局捕获
  • 有注解场景:通过 @SentinelResource 手动指定 “资源名”(如 value=“byId”),熔断规则的资源名需与注解中的 value 一致才能生效。可自定义资源名,并通过注解参数指定回调方法(如 fallback、blockHandler),优雅处理异常。

@SentinelResource 注解的核心价值在于精细化控制资源的异常处理逻辑,其参数定义的各类回调方法及调用时机如下图:

参数分类具体参数名方法作用调用时机(触发条件)处理的异常类型方法要求
熔断 / 限流异常处理blockHandler处理 Sentinel 主动拦截的异常当资源触发熔断(DegradeException)、限流(FlowException)、授权规则(AuthorityException)等 Sentinel 规则时触发。仅处理 BlockException 及其子类(Sentinel 框架抛出的异常)1. 必须包含原方法的所有参数(顺序一致)。
2. 最后必须额外添加一个 BlockException 类型的参数(用于接收 Sentinel 抛出的异常)。
3. 返回值类型必须与原方法一致。
4. 权限为 public,可在当前类中定义(非静态)或其他类中定义(静态,需配合 blockHandlerClass)。
blockHandlerClass指定 blockHandler 方法所在的类配合 blockHandler 使用,当回调方法不在当前类时,需指定该类(方法需为静态方法)。同上
业务异常处理fallback处理业务逻辑抛出的异常当资源的业务代码抛出非 BlockException 的异常(如 RuntimeException、自定义异常)时触发。所有非 BlockException 的异常(业务异常)1. 参数需与原方法一致(顺序一致),或在最后额外添加一个 Throwable 类型的参数(用于接收业务异常)。
2. 返回值类型必须与原方法一致。
3. 权限为 public,可在当前类中定义(非静态)或其他类中定义(静态,需配合 fallbackClass)。
fallbackClass指定 fallback 方法所在的类配合 fallback 使用,当回调方法不在当前类时,需指定该类(方法需为静态方法)。同上
全局兜底处理defaultFallback所有异常的默认兜底处理(优先级最低)当 blockHandler 或 fallback 未配置,或配置的方法无法匹配异常时触发(作为最终兜底)。所有异常(BlockException + 业务异常)1. 无参数,或仅包含一个 Throwable 类型的参数(用于接收异常)。
2. 返回值类型必须与原方法一致。
3. 权限为 public,仅能在当前类中定义(非静态)。
异常忽略exceptionsToIgnore指定无需处理的异常类型被忽略的异常不会进入 fallback 或 defaultFallback,会直接向上抛出。自定义指定的异常(如 NullPointerException)

当多个方法同时配置时,执行顺序为:blockHandler(若触发 BlockException) → fallback(若触发业务异常) → defaultFallback(若前两者未执行或失效)。

热点参数限流:

访问资源参数索引为0(取第1个参数),类型为int,值为3,达到阈值10时进行限流
在这里插入图片描述

需要在provider-7790的controller中设置@SentinelResource注解(前面在异常数中设置过了)

  • 资源名:需要限流的资源标识,需与代码中 @SentinelResource 注解的 value 或接口 URL 完全一致(此处为 byId)。
  • 参数索引:指定对方法的第几个参数进行热点限流。例如,参数索引=0 表示对方法的第一个参数进行限流。
  • 单机阈值:在 “统计窗口时长” 内,若所有参数值的请求总 QPS 超过该阈值,触发限流。此处配置为 1,表示 2 秒内总请求 QPS 超过 1 就会限流。
  • 统计窗口时长:每多少秒统计一次请求数,判断是否超过阈值。
  • 参数例外项:对特定参数值设置 “例外限流阈值”
    • 参数类型:指定例外参数的类型(此处为 int)。
    • 参数值:指定需要特殊处理的参数值(此处为 1)。
    • 限流阈值:该参数值的专属 QPS 阈值(此处为 1)。

@SentinelResource注解

@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。@SentinelResource注解包含以下属性:

  • value:资源名称,必需项(不能为空)
  • entryType:entry 类型,可选项(默认为 EntryType.OUT)
  • blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可
    选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
    fallback 函数签名和位置要求:
    返回值类型必须与原函数返回值类型一致;
    方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
    fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
    返回值类型必须与原函数返回值类型一致;
    方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
    defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

基于nacos配置中心进行规则持久化

在provider-7790的pom文件中引入sentinel持久化依赖,使用naocs进行持久化存储sentinel限流、熔断规则,

<!--sentinel利用nacos做持久化-->
  <dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
  </dependency>

修改application.yml配置
在这里插入图片描述

server:
port: 7790
spring:
application:
name: provider-7790 #往注册中心放的服务名称,一般与项目名保持一致(服务名称不能重复)
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8850
username: nacos
password: nacos
sentinel:
transport:
dashboard: 127.0.0.1:9999 #连接Sentinel控制台dashboard的信息
port: 8719 #TCP协议 与dashboard通信的端口(默认8719)
enabled: true #开启sentinel 默认true
eager: true #取消控制台懒加载 立即初始化dashboard与sentinel
datasource: #sentinel配置数据源
ds1:
nacos:
server-addr: 127.0.0.1:8850 # nacos服务地址
namespace: 935f0c39-db1c-4fc0-a997-35cd6f929740
data-id: ${spring.application.name}-flow #naocs中的配置文件名称,可随意填写,一般都会对应服务名
group-id: DEFAULT_GROUP
data-type: json # 数据格式
rule-type: flow # 规则类型:流控
feign:
circuitbreaker:
enabled: true # 开启熔断处理

在nacos配置中心创建文件:
在这里插入图片描述
在这里插入图片描述

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

重启provider-7790(没有持久化存储不会保留限流规则),查看sentinel流控规则,会发现有我们在nacos中配置的流控规则(在nacos中持久化存储)。
在这里插入图片描述

流量控制参数:

Filed说明默认值
resource资源名,资源名是限流规则的作用对象
count限流阈值
grade限流阈值类型,QPS 模式(1)或并发线程数模式(0)QPS 模式
limitApp流控针对的调用来源default,代表不区分调用来源
strategy调用关系限流策略:直接、链路、关联根据资源本身 (直接)
controlBehavior流控效果(直接拒绝/WarmUp/匀速+排队等待),不支持按调用关系限流直接拒绝
clusterMode是否集群限流

熔断降级配置:
0慢调用比例 1异常比例 2异常数

Field说明默认值
resource资源名,即规则的作用对象
grade熔断策略,支持慢调用比例/异常比例/异常数策略慢调用比例
count慢调用比例模式下为慢调用临界RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow熔断时长,单位为 s
minRequestAmount熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0引入)5
statlntervalMs统计时长(单位为 ms),如60*1000 代表分钟级(1.8.0引入)1000 ms
slowRatioThreshold慢调用比例阈值,仅慢调用比例模式有效 (1.8.0引入)

热点参数配置:

属性说明默认值
resource资源名,必填
count限流阈值,必填
grade限流模式QPS 模式
durationlnSec统计窗口时间长度(单位为秒),1.6.0版本开始支持1s
controlBehavior流控效果(支持快速失败和匀速排队模式),1.6.0版本开始支持快速失败
maxQueueingTimeMs最大排队等待时长(仅在匀速排队模式生效),1.6.0版本开始支持0ms
paramldx热点参数的索引,必填,对应 sphu.entry(xx, args)中的参数索引位置
paramFlowltemList参数例外项,可以针对指定的参数值单独设置限流阈值,不受前面count阈值的限制。仅支持基本类型和字符串类型
clusterMode是否是集群参数流控规则false
clusterConfig集群流控相关配置

注意:
nacos可以创建多个配置文件,flow流控, degrade 降级,param-flow热点

项目中yaml配置

server:
port: 7790
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel:
transport:
dashboard: 127.0.0.1:9999 #连接dashboard
port: 8719
enabled: true
eager: true # 取消控制台懒加载 立即初始化dashboard与sentinel
datasource:
ds1: #限流配置
nacos:
server-addr: 127.0.0.1:8848
data-id: "${spring.application.name}-flow"
group-id: DEFAULT_GROUP
data-type: json
rule-type: flow
ds2: #熔断降级配置
nacos:
server-addr: 127.0.0.1:8848
data-id: "${spring.application.name}-degrade"
group-id: DEFAULT_GROUP
data-type: json
rule-type: degrade #指定为熔断降级规则
ds3: #热点参数限流配置
nacos:
server-addr: 127.0.0.1:8848
data-id: "${spring.application.name}-param-flow"
group-id: DEFAULT_GROUP
data-type: json
rule-type: param-flow
application:
name: bill-consumer-7790

bill-consumer-7790-flow 配置

[
{
"resource": "/bill/find",
"limitApp": "default",
"grade": 1,
"count": 2,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
},
{
"resource": "/bill/find1",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]

bill-consumer-7790-degrade配置

[
{
"resource": "abc",
"grade": 0,
"count": 2,
"timeWindow": 1,
"minRequestAmount": 1,
"statIntervalMs": 5
}
]

bill-consumer-7790-param-flow 配置

[
{
"resource": "abc",
"paramIdx": 0,
"count": 10,
"burst": 5,
"duration": 1,
"controlBehavior": 0,
"maxQueueingTimeMs": 500
}
]

上述 JSON 示例中的各项含义如下:

  • resource :资源名称,对应到你在代码中要进行热点参数限流保护的业务逻辑方法或接口等的标识,可以自定义,但要和代码中的设置一致。
  • paramIdx :热点参数的索引位置,从 0 开始计数,表示要基于哪个参数进行热点参数限流判断。比如你的业务方法有多个参数,这里指定要关注哪个参数的热点情况。
  • count :限流阈值,即单位时间内允许通过的请求次数。
  • burst :突发量,允许在短时间内超过限流阈值的额外请求数量。
  • duration :统计的时间窗口单位,这里设置为 1 表示以秒为单位(也可以根据需要设置为其他时间单位,如分钟等,对应的参数值不同)。
  • controlBehavior :流控效果,0 表示快速失败(达到限流阈值直接拒绝后续请求),还有其他可选值对应不同的流控策略(比如匀速排队等)。
  • maxQueueingTimeMs :最大排队等待时间(毫秒),当使用匀速排队等流控策略时生效,指定请求在排队等待通过限流时的最大等待时长。
posted @ 2025-12-10 17:11  yangykaifa  阅读(15)  评论(0)    收藏  举报