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.rhkb.cn/news/362592.html

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

相关文章

数据库使用笔记

1.mysql数据库频繁访问导致连接超时 解决办法一&#xff1a; 优化查询&#xff1a;检查并优化SQL查询语句&#xff0c;减少不必要的数据库调用。增加连接池大小&#xff1a;如果应用程序使用连接池&#xff0c;可以考虑增加连接池的最大连接数。&#xff08;注&#xff1a;不能…

Linux线程互斥锁

目录 &#x1f6a9;看现象&#xff0c;说原因 &#x1f6a9;解决方案 &#x1f6a9;互斥锁 &#x1f680;关于互斥锁的理解 &#x1f680;关于原子性的理解 &#x1f680;如何理解加锁和解锁是原子的 &#x1f6a9;对互斥锁的简单封装 引言 大家有任何疑问&#xff0c;可…

Unity踩坑记录

1. 如果同时在父物体和子物体上挂载BoxCollider&#xff0c;那么当使用&#xff1a; private void OnTriggerEnter2D(Collider2D collision){if (collision.CompareTag("CardGroup")){_intersectCardGroups.Add(collision.GetComponent<CardGroup>());}} 来判…

掌握SEO:如何优化用ChatGPT生成的文章以提升搜索排名

在数字化时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已经成为网站流量的重要来源。随着人工智能技术的进步&#xff0c;越来越多的人开始使用ChatGPT等AI工具来生成文章。然而&#xff0c;虽然这些工具可以快速生成内容&#xff0c;但要确保这些内容在搜索引擎中…

World of Warcraft [CLASSIC] Level 70 Dire Maul (DM)

[月牙钥匙] [大型爆盐炸弹] World of Warcraft [CLASSIC] Level 70 厄运之槌&#xff0c;完美贡品&#xff0c;Dire Maul &#xff08;DM&#xff09; Foror‘s Compendium of Dragon Slaying 佛洛尔的屠龙技术纲要 因为不是兽王宝宝&#xff0c;而且开始位置放的不对&am…

WPF文本绑定显示格式StringFormat设置-特殊格式时间日期和多数据绑定

WPF文本绑定显示格式StringFormat设置 特殊格式设置日期/时间使用系统默认样式自定义格式&#xff1a; 绑定多个属性&#xff08;多重绑定&#xff09;多重绑定中的特殊字符示例&#xff1a; 特殊格式设置 在Textblock等文本控件中&#xff0c;我们经常要显示一些日期和时间&a…

【C++:list】

list概念 list是一个带头的双向循环链表&#xff0c;双向循环链表的特色&#xff1a;每一个节点拥有两 个指针进行维护&#xff0c;俩指针分别为prev和next,prev指该节点的前一个节点&#xff0c;next为该节点的后一个节点 list的底层实现中为什么对迭代器单独写一个结构体进行…

浏览器扩展V3开发系列之 chrome.contextMenus 右键菜单的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.contextMenus 允许开发者向浏览器的右键菜单添加自定义项。 在使用 chrome.contextMenus 之前…

使用命令行创建uniapp+TS项目,使用vscode编辑器

一:如果没有pnpm,先安装pnpm 二:使用npx工具和degit工具从 GitHub 上的 dcloudio/uni-preset-vue 仓库克隆一个名为 vite-ts 的分支,到项目中. 执行完上面命令后,去manifest.json添加appid(自己微信小程序的Id),也可不执行直接下一步,执行pnpm install ,再执行pnpm:dev:mp-weix…

【技巧】如何检查多个GPU之间是否支持P2P通信

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 需要用到cuda_samples&#xff1a;GitHub - NVIDIA/cuda-samples 该工具的详细解释可以看这个&#xff1a; 【知识】详细介绍 CUDA Samples 示例工程…

利用Python控制终端打印字体的颜色和格式

利用Python控制终端打印字体的颜色和格式—操作详解&#xff08;ANSI转义序列&#xff09; 一、问题描述二、ANSI转义序列三、具体代码和显示效果&#xff08;看懂这段代码&#xff0c;以后可随心控制字体的打印格式&#xff09; 欢迎学习交流&#xff01; 邮箱&#xff1a; z……

Redis-使用 jedis 操作数据

文章目录 1、Jedis简介2、环境准备3、创建maven普通项目,导入如下依赖4、测试JAVA程序和Redis之间的通信 1、Jedis简介 "Jedis" 通常是作为 "Java Redis" 的缩写或简称来理解的。Java Embedded Data Structures Interface 表示 Java嵌入式数据结构接口 2、…

9.二维数组的遍历和存储

二维数组的遍历和存储 二维数组的遍历 二维数组a[3][4],可分解为三个一维数组,其数组名分别为: 这三个一维数组都有4个元素,例如:一维数组a[0]的 元素为a[0][0],a[0][1],a[0][2],a[0][3]。所以遍历二维数组无非就是先取出二维数组中得一维数组, 然后再从一维数组中取出每个元…

TextRank 算法

第1关&#xff1a;Jieba 在关键词提取中的应用 任务描述 本关任务&#xff1a;根据本关所学有关使用 Jieba 库进行关键词提取的知识&#xff0c;编写使用 Jieba 模块进行关键词提取的程序&#xff0c;并通过所有测试用例。 相关知识 为了完成本关任务&#xff0c;你需要掌握…

oracle12c到19c adg搭建(六)切换后12c备库服务器安装19c软件在19c主库升级数据字典后尝试同步

一、安装19c软件 参考文章oracle12c到19c adg搭建&#xff08;三&#xff09;oracle19c数据库软件安装 二、原主库尝试通过19c软件启动数据库 2.1复制12c的相关参数文件和密码文件到19c目录 注意:密码文件需要从已切换主库19c传过来 [oracleo12u19p ~]$ cd /u01/app/oracle…

ubuntu多版本cuda如何指定cuda版本

本文作者&#xff1a; slience_me ubuntu多版本cuda如何指定cuda版本 文章目录 ubuntu多版本cuda如何指定cuda版本1. 关于cuda设置1.1 查看当前安装的 CUDA 版本1.2 下载并安装所需的 CUDA 版本1.3 设置环境变量1.4 验证切换1.5 安装对应的 NVIDIA 驱动程序 2. 设置环境变量2.1…

提取url中的参数

let url https://alibaba.com?a1&b2&c3#hash function queryUrlParams(URL){let url URL.split(?)[1];const urlSearchParams new URLSearchParams(url);console.log(url1, urlSearchParams);console.log(entries,urlSearchParams.entries())const params Object…

.hmallox勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复

导言&#xff1a; 在当今数字化时代&#xff0c;勒索病毒已经成为网络安全的一大威胁&#xff0c;其中包括了最近出现的.hmallox勒索病毒。这类恶意软件不仅能够对计算机系统进行加密&#xff0c;还会要求用户支付赎金以换取解密密钥&#xff0c;给个人用户和企业带来了严重的…

HTTP详解

目录 1.定义 2.工作流程 3.Fiddler 3.1 使用 3.2 工作原理 4.URL 5.请求和响应 5.1 请求 5.2 响应 6.GET和POST 6.1 经典面试题&#xff1a;GET和POST的区别 6.2 GET 6.3 POST 7.请求报头&#xff08;Header&#xff09; 7.1 HOST 7.2 Content-Length 7.3 …

说一说ABAP CDS View的发展历史与特性

1. 背景 随着SAP Fiori应用程序的兴起&#xff0c;SAP领域的小伙伴接触和使用ABAP CDS View的机会也是越来越多。今天&#xff0c;让我们花些时间&#xff0c;一起在了解下这项技术的设计初衷和发展历史。 2. 设计初衷 说起ABAP CDS View&#xff0c;就不得不提及SAP HANA。…