SpringCloud Alibaba Sentinel中@SentinelResource使用实践总结

Sentinel 提供了 @SentinelResource 注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。

注意:注解方式埋点不支持 private 方法。

官网地址:注解埋点支持

【1】资源名称限流

① controller方法

@GetMapping("/byResource")
@SentinelResource(value = "byResource",blockHandler = "handleException")
public CommonResult byResource()
{return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
}
public CommonResult handleException(BlockException exception)
{return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
}

这里 blockHandler 指定了超出规则限制后的处理方法handleException。

② 添加流控规则

如下所示,我们对 byResource 这个资源添加规则设置QPS/1。那么当请求QPS>1时,就会触发我们的 blockHandler = handleException 方法,返回错误信息。

在这里插入图片描述

在这里插入图片描述

其默认也支持根据URL进行限流,如下图所示,当我们访问了http://localhost:8401/byResource 时,簇点链路界面自动会有两个资源:/byResourcebyResource

不建议同时对URL和自定义命名资源添加规则,会导致混乱。

在这里插入图片描述

URL流控限制不会使用我们自定义的blockHandler 方法,会返回默认的 Blocked by Sentinel (flow limiting)

【2】抽离blockHandler

也就是将blockHandler处理从业务类抽离出来,单独放在一个异常处理类比如CustomerBlockHandler。

如下所示修改业务方法:

@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handleException")public CommonResult customerBlockHandler(){return new CommonResult(200,"按客户自定义限流处理逻辑");}

述配置:找CustomerBlockHandler类里的handleException方法进行兜底处理。

创建CustomerBlockHandler ,定义handleException方法:

public class CustomerBlockHandler {public static CommonResult handleException(BlockException exception){return new CommonResult(2020,"自定义的限流处理信息......CustomerBlockHandler");}
}

抽离也是符合单一职责原则(Single Responsibility Principle)-每一个类(接口)应该专注于做一件事情。常常可见接口多继承现象

【3】注解属性说明

@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 逻辑中,而是会原样抛出。

| 注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理。

特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出。

【4】服务熔断实践

如下所示,有四种配置实例:

  • ① @SentinelResource(value = “fallback”) 只定义了资源
  • ② @SentinelResource(value = “fallback”,fallback = “handlerFallback”)定义了服务熔断处理,也就是针对运行时异常
  • ③ @SentinelResource(value = “fallback”,blockHandler = “blockHandler”)定义了违背规则处理,也就是违背了Sentinel定义规则比如QPS/1
  • ④ @SentinelResource(value = “fallback”,fallback = “handlerFallback”,blockHandler = “blockHandler”)同时定义了规则处理和服务熔断处理
public static final String SERVICE_URL = "http://nacos-payment-provider";@Resourceprivate RestTemplate restTemplate;@RequestMapping("/consumer/fallback/{id}")
//    @SentinelResource(value = "fallback")   // 没有配置
//    @SentinelResource(value = "fallback",fallback = "handlerFallback")//fallback
//    @SentinelResource(value = "fallback",blockHandler = "blockHandler")//blockhandler
//    @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler")//fallback+blockhandler@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",exceptionsToIgnore = RuntimeException.class)public String fallback(@PathVariable("id") Long id){String result = restTemplate.getForObject(SERVICE_URL+"/payment/"+id,String.class,id);if (id==4){throw new RuntimeException("非法参数异常");}return result;}public String handlerFallback(@PathVariable Long id){return id+"异常";}public String blockHandler(Long id, BlockException e){return "blockHandler异常";}

exceptionsToIgnore = RuntimeException.class 表示忽略处理的异常,那么异常将会直接被原样抛出。

对于④,blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。


那么同样出于单一职责原则,我们可以定义blockHandlerClass 和fallbackClass 来讲异常处理逻辑抽离出来。

@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
exceptionsToIgnore = RuntimeException.class,
blockHandlerClass = XXXXX,
fallbackClass = XXXXXX)

【5】服务熔断与Feign的实践

主启动类:

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

yml配置:

server:port: 84spring:application:name: nacos-order-consumercloud:nacos:discovery:server-addr: localhost:8848sentinel:transport:dashboard: localhost:8080port: 8719service-url:nacos-user-service: http://nacos-payment-providerfeign:sentinel:enabled: true

pom依赖:

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 后续做持久化用到 -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

定义feign接口:

@FeignClient(value = "nacos-payment-provider",fallback = PaymentFailService.class)
public interface PaymentService {@GetMapping("/payment/{id}")public String payment(@PathVariable("id") Long id);
}

这里fallback = PaymentFailService.class 将服务降级处理方法抽离了出来:

@Component
public class PaymentFailService implements PaymentService {@Overridepublic String payment(Long id) {return "feign失败调用";}
}

业务controller:

@Resource
private PaymentService paymentService;@GetMapping("consumer/payment/{id}")
public String payment(@PathVariable("id") Long id){return paymentService.payment(id);
}

可以看到与Feign整合这里我们只能定义fallback,不能像【4】中那样进行多样自定义配置。那么我们可以在Feign接口方法上定义@SentinelResource注解吗?

答案是不可以,如下所示,会抛异常:java.lang.IllegalStateException: Wrong state for SentinelResource annotation

在这里插入图片描述

【6】熔断框架比较

在这里插入图片描述

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

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

相关文章

SpringBoot实现发送验证码功能

提示&#xff1a;本次内容主要学习如何做一个发送验证码和识别验证码的功能 文章目录 目录 文章目录 前言 一、图片验证码是什么&#xff1f; 二、使用步骤 1.创建验证码生成 2.生成验证码 总结 前言 提示&#xff1a;本次内容主要学习如何做一个发送验证码和识别验证码…

LabVIEW技术交流-布尔灯仿真数码管

问题来源 闲来无事&#xff0c;逛论坛问答&#xff0c;看到这样一个问题&#xff0c;觉得有意思&#xff0c;就自己尝试下。 这个功能其实是不难的&#xff0c;就是显示不同的数值时&#xff0c;对相应的布尔灯进行真假值操作就行了。但是我又想到了更有趣的玩法&#xff0c;能…

C#学习系列之DataGrid无故添加空行

C#学习系列之DataGrid无故添加空行 前言解决前解决后总结 前言 采用别人的轮子&#xff0c;想在基础上改界面&#xff0c;但是copy后&#xff0c;无论怎么样都会有空行&#xff0c;实在是绑定数据的输入没有任何赋值。 解决前 绑定的数据中输入三组数据&#xff0c;但是没有第…

手写原生Ajax

打开请求: xhr.open(GET, /api/lian, true); 这里使用open方法初始化一个请求。参数分别为&#xff1a; GET&#xff1a;请求的方法&#xff0c;这里是GET方法&#xff0c;用于从服务器获取数据。/api/lian&#xff1a;请求的URL&#xff0c;表示将向服务器的/api/lian端点发送…

【Academy】测试WebSockets安全漏洞Testing for WebSockets security vulnerabilities

测试WebSockets安全漏洞Testing for WebSockets security vulnerabilities 概述WebSockets是什么?HTTP和WebSockets有什么区别&#xff1f;如何建立WebSocket连接&#xff1f;WebSocket消息看起来像什么&#xff1f; 操纵WebSocket流量拦截和修改WebSocket消息重放和生成新的W…

Python常用模块

math模块 Python官方提供的 math 模块进行数学运算&#xff0c;如指数、对数、平方根和三角函数等运算。math 模块中的函数只是整数和浮点&#xff0c;不包括复数&#xff0c;复数计算需要使用 cmath模块。在使用 math 模块前要先导入 math 模块。 舍入函数 函数名说明math.…

Qt 智能指针类详解

在Qt框架中&#xff0c;提供了多种智能指针类&#xff0c;用于管理对象的生命周期和内存。常见的包括QPointer、QSharedPointer、QWeakPointer和QScopedPointer。它们各自有不同的用途和行为特点。本文将详细介绍这些类的区别和使用场景。 QPointer QPointer是一个模板类&…

链式队列算法库构建

学习贺利坚老师课程,构建链式队列算法库 数据结构之自建算法库——链队&#xff08;链式队列&#xff09;_数据结构函数链队列的算法框架有哪些-CSDN博客文章浏览阅读6.2k次&#xff0c;点赞3次&#xff0c;收藏9次。本文针对数据结构基础系列网络课程(3)&#xff1a;栈和队列…

低碳短视频:成都柏煜文化传媒有限公司

低碳短视频&#xff1a;绿色传播的新风尚 随着全球气候变化和环境问题日益严峻&#xff0c;低碳生活已经成为人们追求的新风尚。在这个背景下&#xff0c;低碳短视频应运而生&#xff0c;以其独特的方式传播绿色理念&#xff0c;推动低碳生活方式的普及。成都柏煜文化传媒有限…

RedisConnectionException: Unable to connect to 127.0.0.1:6379

idea报错无法连接到redis org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.…

printf趣味代码,打印图案

文章目录 1.打印佛祖2.打印猫猫 (闪烁效果) 1.打印佛祖 #include <stdio.h>void budda_bless(){printf("///\n\ // _ooOoo_ //\n\ // o8888888o //\n\ // …

文件I/O基础-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

文件I/O基础 本章将介绍Linux应用编程中最基础的知识&#xff0c;即文件I/O&#xff08;Input/Output&#xff09;。文件I/O指的是对文件进行读写操作&#xff0c;在Linux系统中一切皆文件&#xff0c;这是Linux系统设计的核心理念&#xff0c;因此文件I/O操作既是基础又是最重…

【软件下载】Folx详细安装教程视频-Folx软件最新版下载

根据大数据调查表明Acceleration PRO下载&#xff1a;抽出多达10个流的故障能够显着提高下载速度。根据行业数据显示与iTunes PRO集成&#xff1a;通过将Folx集成到iTunes来下载歌曲和视频&#xff0c;能够在下载后立即自动添加到iTunes库。实际上我们可以这样讲通过代理下载&a…

udp udpClient 聊天室

简介 1、UDP&#xff08;User Data Protocol&#xff0c;用户数据报协议&#xff09; &#xff08;1&#xff09; UDP是一个非连接的协议&#xff0c;传输数据之前源端和终端不建立连接&#xff0c;当它想传送时就简单地去抓取来自应用程序的数据&#xff0c;并尽可能快地把它…

Vue38 安装脚手架 vue-cli ,并使用脚手架创建项目

安装脚手架 vue-cli &#xff0c;并使用脚手架创建项目 第一步 安装脚手架 npm config set registry https:\\[registry.npmmirror.com // 切换淘宝镜像 npm install -g vue/cli第二步 切换到创建项目的目录&#xff0c;创建项目 cd XXX vue create XXX第三步 启动项目 npm…

化茧成蝶 | 继HuggingFace首家落地大模型具身智能场景

关于具身智能的起源 近年来&#xff0c;大语言模型&#xff08;LLMs&#xff09;的兴起给机器人领域带来了革命性的改变&#xff0c;大模型赋予了传统机器人理解和推理的能力&#xff0c;让具身智能这一概念再度出现在大众的视角中。OpenCSG 作为国内 AI 开源社区的先锋&#…

[AI MoneyPrinterTurbo] 一键成片,超级印钞机

今天&#xff0c;我们将踏上一段关于MoneyPrinterTurbo的探索之旅&#xff0c;这是一个文生视频工具&#xff0c;旨在让视频创作变得轻松而有趣。 故事的开始 想象一下&#xff0c;你只需要提供一个视频主题或关键词&#xff0c;剩下的——视频文案、素材、字幕、背景音乐&am…

openCV3.0 C++ 学习笔记补充(自用 代码+注释)---持续更新 二(51-)

环境&#xff1a;OpenCV3.2.0 VS2015 51、Mean-Shift算法分割图像 cv::pyrMeanShiftFiltering() 参考链接&#xff1a;【从零学习OpenCV 4】分割图像——Mean-Shift分割算法 Mean-Shift算法又被称为均值漂移法&#xff0c;是一种基于颜色空间分布(彩色图像的像素值)的图像分割…

pycharm鼠标变成小方块

异常图片&#xff1a; 异常原因&#xff1a;误动了键盘insert键 解决方法&#xff1a;Fninsert

根据配置生成一个合并单元格的table表格的html代码

​分享最近工作中遇到的一个场景&#xff1a;导出表格&#xff0c;需要准备好表格的html代码&#xff0c;此表格支持最上面的表头合并且居中展示表格标题&#xff0c;如果上下行数据有相同的&#xff0c;则要上下合并单元格 封装了一个如下的方法 const configToTable (conf…