谷粒商城-高级篇-Sentinel-分布式系统的流量防卫兵

1、基本概念

1.1、熔断降级限流

1、什么是熔断

A 服务调用 B 服务的某个功能,由于网络不稳定问题,或者 B 服务卡机,导致功能时间超长。如果这样子的次数太多。我们就可以直接将 B 断路了( A 不再请求 B 接口),凡是调用 B 的直接返回降级数据,不必等待 B 的超长执行。 这样 B 的故障问题,就不会级联影响到 A 。

2、什么是降级

整个网站处于流量高峰期,服务器压力剧增,根据当前业务情况及流量,对一些服务和页面进行有策略的降级[ 停止服务,所有的调用直接返回降级数据 ] 。以此缓解服务器资源的的压力,以保证核心业务的正常运行,同时也保持了客户和大部分客户的得到正确的相应。
异同:
相同点:
为了保证集群大部分服务的可用性和可靠性,防止崩溃,牺牲小我
用户最终都是体验到某个功能不可用
不同点:
熔断是被调用方故障,触发的系统主动规则
降级是基于全局考虑,停止一些正常服务,释放资源

3、什么是限流

对打入服务的请求流量进行控制,使服务能够承担不超过自己能力的流量压力

1.2、Sentinel 简介

官方文档: 介绍 · alibaba/Sentinel Wiki · GitHub
项目地址: GitHub - alibaba/Sentinel: A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 分为两个部分 :
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的Tomcat 等应用容器。
Sentinel 基本概念
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。

只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来 。大部分情况下,可以使用方法签名,URL ,甚至服务名称作为资源名来标示资源。


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

1.3、Hystrix 与 Sentinel 比较

2、整合SpringBoot

1、整合sentinel流程:

1)、导入依赖 spring-cloud-starter-alibaba-sentinel

2)、下载Sentinel的控制台

3)、配置sentinel控制台地址信息

4)、在控制台调整参数【默认所有的流控设置保存在项目内存中,重启失效】

2、每一个微服务导入信息审计模块spring-boot-starter-actuator

并配置management.endpoints.web.exposure.include=* (暴露Sentinel的信息)

3、自定义Sentinel的流控返回数据

gulimall-common模块的pom.xml文件添加sentinel熔断、限流依赖

    <!--sentinel熔断、限流--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>

gulimall-seckill模块的pom.xml文件添加统计审计信息依赖

    <!--统计审计信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>

找到项目里sentinel对应的版本

去官网下载该版本的控制台

Tags · alibaba/Sentinel · GitHub

java -jar sentinel-dashboard-1.8.6.jar --server.port=8333

打开http://localhost:8333

用户名:sentinel

密码:sentinel

在每个服务配置里配置Sentinel

#Sentinel
#Sentinel控制台地址
spring.cloud.sentinel.transport.dashboard=localhost:8333
#Sentinel传输端口:默认 8719,假如被占用了会自动从 8719 开始依次 +1 扫描,直至找到未被占用的端口
spring.cloud.sentinel.transport.port=8719
#暴露的 endpoint 路径为 /actuator/sentinel
#Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、
#当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
management.endpoints.web.exposure.include=*

未使用自定义流控响应

流控生效(多次刷新,只调用少数)

http://seckill.gulimall.com/getCurrentSeckillSkus

3、自定义流控响应


添加“com.atguigu.gulimall.seckill.config.SeckillSentinelConfig”类,代码如下:

package com.atguigu.gulimall.seckill.config;import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.common.utils.R;
import org.springframework.context.annotation.Configuration;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;// 自定义sentinel流控响应
@Configuration
public class GulimallSeckillSentinelConfig {public GulimallSeckillSentinelConfig() {// 自定义返回字符串//{"msg":"请求次数太多,请稍后再试","code":10003}WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {@Overridepublic void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {R error = R.error(BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getCode(), BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getMsg());response.setCharacterEncoding("UTF-8");response.setContentType("application/json");response.getWriter().write(JSON.toJSONString(error));}});}}

@Configuration
public class SeckillSentinelConfig implements BlockExceptionHandler {/*** 2.2.0以后的版本实现的是BlockExceptionHandler;以前的版本实现的是WebCallbackManager* @param httpServletRequest* @param httpServletResponse* @param e* @throws Exception*/@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {R error = R.error(BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getCode(), BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getMsg());httpServletResponse.setCharacterEncoding("UTF-8");httpServletResponse.setContentType("application/json");httpServletResponse.getWriter().write(JSON.toJSONString(error));}/*** 因为版本冲突导致无法引入 WebCallbackManager*/
//    public SeckillSentinelConfig() {
//        WebCallbackManager.setUrlBlockHandler((request, response, ex) -> {
//            R error = R.error(BizCodeEnum.TOO_MANY_REQUESTS_EXCEPTION.getCode(), BizCodeEnum.TOO_MANY_REQUESTS_EXCEPTION.getMsg());
//            response.setCharacterEncoding("UTF-8");
//            response.setContentType("application/json");
//            response.getWriter().write(JSON.toJSONString(error));
//        });
//    }
}

返回结果

4、Sentinel全服务引入


每个微服务引入actuator依赖

       <!--统计审计信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>

每个配置文件配置以下参数

#Sentinel
#Sentinel控制台地址
spring.cloud.sentinel.transport.dashboard=localhost:8333
#Sentinel传输端口:默认 8719,假如被占用了会自动从 8719 开始依次 +1 扫描,直至找到未被占用的端口
spring.cloud.sentinel.transport.port=8719
#暴露的 endpoint 路径为 /actuator/sentinel
#Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、
#当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
management.endpoints.web.exposure.include=*

流量控制

设置超时时间等参数。


5、feign熔断降级

使用Sentinel来保护Feign的远程调用。

主页 · alibaba/Sentinel Wiki · GitHub

什么是熔断降级

除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。

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

注意:本文档针对 Sentinel 1.8.0 及以上版本。1.8.0 版本对熔断降级特性进行了全新的改进升级,请使用最新版本以更好地利用熔断降级的能力。

熔断降级设计理念

在限制的手段上, Sentinel 和 Hystrix 采取了完全不一样的方法。
Hystrix 通过线程池隔离的方式,来对依赖(在 Sentinel 的概念中对应资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本(过多的线程池导致线程数目过多),还需要预先给各个资源做线程池大小的分配。


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

熔断策略

Sentinel 提供以下几种熔断策略:

1.慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
2.异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
3.异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
整合测试:

https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/se%20ntinel-example/sentinel-feign-example/readme-zh.md

默认情况下,sentinel是不会对feign进行监控的,需要开启配置

在gulimall-product类配置文件添加配置

#sentinel是不会对feign进行监控的,需要开启配置
feign.sentinel.enabled=true

5.1、fegin的熔断


使用Sentinel来保护feign远程调用:熔断。

1.调用方的熔断保护开启 feign.sentinel.enabled=true
2.调用方手动指定远程服务的降级策略。远程服务被降级处理,触发我们的熔断回调方法
3.超大浏览的时候,必须牺牲一些远程服务。在服务的提供方(远程服务==>秒杀)指定降级策略; 提供方是在运行。但是不运行自己的业务逻辑。返回的是默认的降级数据(限流的数据)===一般在提供方降级,考虑全局的性能。


gulimall-product服务远程调用gulimall-seckill服务。调用前直接把gulimall-seckill服务宕机,以前不使用sentinel的熔断的时候直接调用会报错。
现在使用sentinel的熔断保护机制,远程调用失败,我们会在调用方实现远程调用类,自定义返回信息给页面。
后台配置熔断策略

定义FeignClient及其降级配置
修改“com.atguigu.gulimall.product.feign.SeckillFeignService”类,代码如下:

@FeignClient(value = "gulimall-seckill",fallback = SeckillFeignServiceFallBack.class)
public interface SeckillFeignService {
@GetMapping("/sku/seckill/{skuId}")
R getSkuSecKillInfo(@PathVariable("skuId") Long skuId);
}


自定义--远程调用失败具体的fallback 实现
添加“com.atguigu.gulimall.product.feign.fallback.SeckillFeignServiceFallBack”类,代码如下:

@Slf4j
@Component
public class SeckillFeignServiceFallBack implements SeckillFeignService {@Overridepublic R getSkuSecKillInfo(Long skuId) {log.info("熔断方法调用.....getSkuSecKillInfo");return R.error(BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getCode(),BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getMsg());}
}

6、自定义受保护资源


spring-cloud-alibaba/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md at 2.2.x · alibaba/spring-cloud-alibaba · GitHub 注意异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。为了统计异常比例或异常数,需要通过 Tracer.trace(ex) 记录业务异常。示例:

Entry entry = null;
try {entry = SphU.entry(key, EntryType.IN, key);// Write your biz code here.// <<BIZ CODE>>
} catch (Throwable t) {if (!BlockException.isBlockException(t)) {Tracer.trace(t);}
} finally {if (entry != null) {entry.exit();}
}

开源整合模块,如 Sentinel Dubbo Adapter, Sentinel Web Servlet Filter 或 @SentinelResource 注解会自动统计业务异常,无需手动调用。

熔断降级规则说明

熔断降级规则(DegradeRule)包含下面几个重要的属性:

熔断器事件监听

Sentinel 支持注册自定义的事件监听器监听熔断器状态变换事件(state change event)。示例:

EventObserverRegistry.getInstance().addStateChangeObserver("logging",(prevState, newState, rule, snapshotValue) -> {if (newState == State.OPEN) {// 变换至 OPEN state 时会携带触发时的值System.err.println(String.format("%s -> OPEN at %d, snapshotValue=%.2f", prevState.name(),TimeUtil.currentTimeMillis(), snapshotValue));} else {System.err.println(String.format("%s -> %s at %d", prevState.name(), newState.name(),TimeUtil.currentTimeMillis()));}});

自定义受保护的资源方法:

1)、代码:

try(Entry entry = SphU.entry("seckillSkus")){

// 业务逻辑

}catch(Exception e){

}

2)、基于注解

@SentinelResource(value = "getCurrentSeckillSkusResource",blockHandler = "blockHandler")

无论1.2一定要配置被限流以后的默认返回

url请求可以设置统一返回 SeckillSentinelConfig

6.1、基于代码的限流


修改“com.atguigu.gulimall.seckill.service.impl.SeckillServiceImpl”类,代码如下:

@Override
public List<SeckillSkuRedisTo> getCurrentSeckillSkus() {try (Entry entry = SphU.entry("seckillSkus")) {// 获取秒杀活动的所有keySet<String> keys = stringRedisTemplate.keys(SESSIONS_CACHE_PREFIX + "*");long currentTime = System.currentTimeMillis();for (String key : keys) {String replace = key.replace(SESSIONS_CACHE_PREFIX, "");String[] split = replace.split("_");long startTime = Long.parseLong(split[0]);long endTime = Long.parseLong(split[1]);// 当前秒杀活动处于有效期内if (currentTime > startTime && currentTime < endTime) {// 获取这个秒杀场次的所有商品信息List<String> range = stringRedisTemplate.opsForList().range(key, -100, 100);BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(SKUKILL_CACHE_PREFIX);assert range != null;List<String> strings = hashOps.multiGet(range);if (!CollectionUtils.isEmpty(strings)) {return strings.stream().map(item -> JSON.parseObject(item, SeckillSkuRedisTo.class)).collect(Collectors.toList());}break;}}} catch (BlockException e) {log.error("资源被限流{}", e.getMessage());}return null;
}

6.2、基于注解的自定义限流

@SentinelResource(value = "getCurrentSeckillSkusResource", blockHandler = "blockHandler")

无论是1,2方式一定要配置被限流以后的默认返回

url请求可以设置统-返回:WebCallbackManager(在config里)

    public List<SeckillSkuRedisTo> blockHandler(BlockException e){log.error("getCurrentSeckillSkusResource被限流了。。。。");return null;}// blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而fallback函数会针对所有类型的异常//基于注解的限流@SentinelResource(value = "getCurrentSeckillSkusResource", blockHandler = "blockHandler")@Overridepublic List<SeckillSkuRedisTo> getCurrentSeckillSkus() {try (Entry entry = SphU.entry("seckillSkus")) {// 获取秒杀活动的所有keySet<String> keys = stringRedisTemplate.keys(SESSIONS_CACHE_PREFIX + "*");long currentTime = System.currentTimeMillis();for (String key : keys) {String replace = key.replace(SESSIONS_CACHE_PREFIX, "");String[] split = replace.split("_");long startTime = Long.parseLong(split[0]);long endTime = Long.parseLong(split[1]);// 当前秒杀活动处于有效期内if (currentTime > startTime && currentTime < endTime) {// 获取这个秒杀场次的所有商品信息List<String> range = stringRedisTemplate.opsForList().range(key, -100, 100);BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(SKUKILL_CACHE_PREFIX);assert range != null;List<String> strings = hashOps.multiGet(range);if (!CollectionUtils.isEmpty(strings)) {return strings.stream().map(item -> JSON.parseObject(item, SeckillSkuRedisTo.class)).collect(Collectors.toList());}break;}}} catch (BlockException e) {log.error("资源被限流{}", e.getMessage());}return null;}

7、网关流控


如果能在网关层就进行流控,可以避免请求流入业务,减小服务压力

Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。

Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模块,此模块中包含网关限流的规则和自定义 API 的实体和管理逻辑:

1.GatewayFlowRule:网关限流规则,针对 API Gateway 的场景定制的限流规则,可以针对不同 route 或自定义的 API 分组进行限流,支持针对请求中的参数、Header、来源 IP 等进行定制化的限流。
2.ApiDefinition:用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合。比如我们可以定义一个 API 叫 my_api,请求 path 模式为 /foo/** 和 /baz/** 的都归到 my_api 这个 API 分组下面。限流的时候可以针对这个自定义的 API 分组维度进行限流。


其中网关限流规则 GatewayFlowRule 的字段解释如下:

resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
resourceMode:规则是针对 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID)还是用户在 Sentinel 中定义的 API 分组(RESOURCE_MODE_CUSTOM_API_NAME),默认是 route。
grade:限流指标维度,同限流规则的 grade 字段。
count:限流阈值
intervalSec:统计时间窗口,单位是秒,默认是 1 秒。
controlBehavior:流量整形的控制效果,同限流规则的 controlBehavior 字段,目前支持快速失败和匀速排队两种模式,默认是快速失败。
burst:应对突发请求时额外允许的请求数目。
maxQueueingTimeoutMs:匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效。


paramItem:参数限流配置。若不提供,则代表不针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换成热点规则。其中的字段:
parseStrategy:从请求中提取参数的策略,目前支持提取来源 IP(PARAM_PARSE_STRATEGY_CLIENT_IP)、Host(PARAM_PARSE_STRATEGY_HOST)、任意 Header(PARAM_PARSE_STRATEGY_HEADER)和任意 URL 参数(PARAM_PARSE_STRATEGY_URL_PARAM)四种模式。
fieldName:若提取策略选择 Header 模式或 URL 参数模式,则需要指定对应的 header 名称或 URL 参数名称。
pattern:参数值的匹配模式,只有匹配该模式的请求属性值会纳入统计和流控;若为空则统计该请求属性的所有值。(1.6.2 版本开始支持)
matchStrategy:参数值的匹配策略,目前支持精确匹配(PARAM_MATCH_STRATEGY_EXACT)、子串匹配(PARAM_MATCH_STRATEGY_CONTAINS)和正则匹配(PARAM_MATCH_STRATEGY_REGEX)。(1.6.2 版本开始支持)


用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则,或通过 GatewayRuleManager.register2Property(property) 注册动态规则源动态推送(推荐方式)。

Spring Cloud Gateway

从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:

route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
使用时需引入以下模块(以 Maven 为例)

gulimall-gateway引入依赖

<!-- 引入sentinel网关限流 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId><version>2.2.0.RELEASE</version>
</dependency>

注意引入的依赖要和gulimall-common的pom里的阿里巴巴版本一致

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

参数解释:

间隔就是:当每秒的请求超过QPS值,启动间隔。2分钟内所有调用这个接口直接返回。不去调用业务代码

自定义返回数据信息

您可以在 GatewayCallbackManager 注册回调进行定制:

setBlockHandler:注册函数用于实现自定义的逻辑处理被限流的请求,对应接口为 BlockRequestHandler。默认实现为 DefaultBlockRequestHandler,当被限流时会返回类似于下面的错误信息:Blocked by Sentinel: FlowException。
注意:

Sentinel 网关流控默认的粒度是 route 维度以及自定义 API 分组维度,默认不支持 URL 粒度。若通过 Spring Cloud Alibaba 接入,请将 spring.cloud.sentinel.filter.enabled 配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。
若使用 Spring Cloud Alibaba Sentinel 数据源模块,需要注意网关流控规则数据源类型是 gw-flow,若将网关流控规则数据源指定为 flow 则不生效。
新增“com.atguigu.gulimall.gateway.config.SentinelGateWayConfig”类,代码如下:

SentinelGateWayConfig(自定义返回类)Mono

@Configuration
public class SentinelGateWayConfig {
// 响应式编程
public SentinelGateWayConfig() {GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {// 网关限流了请求,就会调用此回调@Overridepublic Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {R error = R.error(BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getCode(), BizCodeEnume.TOO_MANY_REQUESTS_EXCEPTION.getMsg());String s = JSON.toJSONString(error);Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(s), String.class);return body;}});
}
}

设置流控规则

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503348.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机租赁平台开发实用指南与市场趋势分析

内容概要 在当今快速变化的科技时代&#xff0c;手机租赁平台的发展如火如荼。随着越来越多的人希望使用最新款的智能手机&#xff0c;但又不愿意承担昂贵的购机成本&#xff0c;手机租赁平台应运而生。这种模式不仅为用户提供了灵活的选择&#xff0c;还为企业创造了新的商机…

计算机网络 (22)网际协议IP

一、IP协议的基本定义 IP协议是Internet Protocol的缩写&#xff0c;即因特网协议。它是TCP/IP协议簇中最核心的协议&#xff0c;负责在网络中传送数据包&#xff0c;并提供寻址和路由功能。IP协议为每个连接在因特网上的主机&#xff08;或路由器&#xff09;分配一个唯一的IP…

NUTTX移植到STM32

STM32移植NUTTX 1. Ubuntu下搭建开发环境1.1 先决条件1.2 下载 NuttX1.3 使用Make 进行编译1.4 烧录运行 2.通过NUTTX点亮LED2.1 部署操作系统2.2 修改配置文件2.3 编译运行程序 开发板&#xff1a;DshanMCUF407 官方开发文档&#xff1a;安装 — NuttX latest 文档 参考文档&…

MITRE ATTCK 简介:初学者指南

网络安全已成为当今数字世界的一个关键问题。随着网络威胁日益复杂&#xff0c;组织需要一种结构化的方法来理解和应对这些风险。这就是 MITRE ATT&CK 框架发挥作用的地方。如果您是网络安全新手或刚刚开始探索威胁分析和缓解&#xff0c;本指南将为 MITRE ATT&CK 提供…

JAVA创建绘图板JAVA构建主窗口鼠标拖动来绘制线条

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

鸿蒙 ArkUI实现地图找房效果

常用的地图找房功能&#xff0c;是在地图上添加区域、商圈、房源等一些自定义 marker&#xff0c;然后配上自己应用的一些筛选逻辑构成&#xff0c;在这里使用鸿蒙 ArkUI 简单实现下怎么添加区域/商圈、房源等 Marker. 1、开启地图服务 在华为开发者官网&#xff0c;注册应用&…

AI Development Notes 1 - introduction with the OpenAI API Development

Official document&#xff1a;https://platform.openai.com/docs/api-reference/chat/create 1. Use APIfox to call APIs 2.Use PyCharm to call APIs 2.1-1 WIN OS.Configure the Enviorment variable #HK代理环境&#xff0c;不需要科学上网(价格便宜、有安全风险&#…

ComfyUI节点安装笔记

AI高速发展&#xff0c;版本更新相当快&#xff08;11月25日才安装的版本v.0.3.4&#xff0c;27日版本就已经更新到v.0.3.5了&#xff09;&#xff0c;在遇到问题&#xff0c;找到问题原因所在的过程中&#xff0c;ComfyUI版本、python版本、节点对环境版本的依赖&#xff0c;本…

小白学Pytorch

小白学Pytorch 发现一个比较好的教程&#xff0c;对于自己来说比较合适&#xff0c;适合从零开始的教程。 1、搭建一个简单的网络 https://www.cnblogs.com/PythonLearner/p/13587092.html 搭建网络这步说的比较清楚&#xff1a; 我们使用nn包中的Sequential搭建网络&#…

如何查看服务器上的MySQL/Redis等系统服务状态和列表

如果呢你知道系统服务名称&#xff0c;要看状态很简单&#xff1a; systemctl status server-name 比如 systemctl status nginxsystemctl status redis # 等 这是一个nginx的示例&#xff1a; 那问题是 当你不知道服务名称时该怎么办。举个例子&#xff0c;比如mysql在启动…

ubuntu开机启动服务

需求背景&#xff1a; 需要监控日志&#xff0c;每次都是手动启动 nohup ./prometheus >/dev/null & nohub ./node_exporter >/dev/null & 需求目标&#xff1a; 重启后系统自动启动服务

路由组件与一般组件的区别

路由组件与一般组件的区别 1. 基本概念 1.1 路由组件 路由组件是指通过路由规则映射的组件&#xff0c;通常放在 pages 或 views 文件夹中。 1.2 一般组件 一般组件是指通过 import 导入后直接使用的组件&#xff0c;通常放在 components 文件夹中。 2. 主要区别 2.1 存…

Qt天气预报系统设计界面布局第四部分右边

Qt天气预报系统 1、第四部分右边的第一部分1.1添加控件 2、第四部分右边的第二部分2.1添加控件 3、第四部分右边的第三部分3.1添加控件3.2修改控件名字 1、第四部分右边的第一部分 1.1添加控件 拖入一个widget&#xff0c;改名为widget04r作为第四部分的右边 往widget04r再拖…

数据库系统概论期末复习

期末考试题型&#xff1a; 选择题 20题 20分 判断题 10题 10分 简答题 4题 20分 SQL语句&#xff1a; &#xff08;select delete update&#xff09;30分 设计题&#xff1a;ER图 和关系模式 ER转关系模式&#xff0c;注意主码&#xff0c;外码的标注 15分 应用题&#xff1a;…

uni-app 页面生命周期及组件生命周期汇总(Vue2、Vue3)

文章目录 一、前言&#x1f343;二、页面生命周期三、Vue2 页面及组件生命周期流程图四、Vue3 页面及组件生命周期流程图4.1 页面加载时序介绍4.2 页面加载常见问题4.3 onShow 和 onHide4.4 onInit4.5 onLoad4.6 onReachBottom4.7 onPageScroll4.8 onBackPress4.9 onTabItemTap…

微信小程序中 “页面” 和 “非页面” 的区别

微信小程序中 “页面” 和 “非页面” 的区别&#xff0c;并用表格进行对比。 核心概念&#xff1a; 页面 (Page)&#xff1a; 页面是微信小程序中用户可以直接交互的视图层&#xff0c;也是小程序的基本组成部分。每个页面都有自己的 WXML 结构、WXSS 样式和 JavaScript 逻辑…

【Linux】传输层协议UDP

目录 再谈端口号 端口号范围划分 UDP协议 UDP协议端格式 UDP的特点 UDP的缓冲区 UDP注意事项 进一步深刻理解 再谈端口号 在上图中&#xff0c;有两个客户端A和B&#xff0c;客户端A打开了两个浏览器&#xff0c;这两个客户端都访问同一个服务器&#xff0c;都访问服务…

大数据架构演变

一、离线数仓 缺点&#xff1a; ETL计算、存储、时间成本高数据处理链路过长无法支持实时、近实时的数据分析数据采集对业务库造成影响 二、Lambda架构&#xff0c;离线实时分开 缺点&#xff1a; 组件多&#xff0c;不方便管理很难保证数据一致数据探查困难&#xff0c;出现…

进程间通讯

简介&#xff1a; 进程间通讯方式有&#xff1a; 1.内存映射&#xff08;mmap&#xff09;&#xff1a; 使用mmap函数将磁盘空间映射到内存 2.管道 3.信号 4.套接字&#xff08;socket&#xff09; 5.信号机制 通过进程中kill函数&#xff0c;去给另一个函数发送信号&a…

毕业项目推荐:基于yolov8/yolov5的行人检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…