首页 > 其他分享 >十三、@SentinelResource

十三、@SentinelResource

时间:2023-07-06 20:25:16浏览次数:36  
标签:String helloDefaultEx 十三 SentinelResource value 限流 fallback port

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

 

@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 函数签名和位置要求:

    1、返回值类型必须与原函数返回值类型一致;

    2、方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。

    3、fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

  • defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:

    1、返回值类型必须与原函数返回值类型一致;

    2、方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。

    3、defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

  • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

 

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

 

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

演示

增加资源:

@RequestMapping("/hello")
@SentinelResource(value = "HelloConsumer-hello", blockHandler = "helloHandle", blockHandlerClass = HelloHanldeErr.class)
public String  hello(@RequestParam(value = "a") String a) {
    return "hello,Consumer,port:" + port;
}

@Slf4j
public class HelloHanldeErr {

    public static String helloHandle(String a, BlockException e) {
        log.error("被限流",e);
        return "系统正忙,请稍后重试";
    }
}

helloHandle方法和hello参数相同,且返回值相同。除了helloHandle最后一个参数为BlockException类型。

 

在Sentinel dashboard中配置流控规则:
 

 

在浏览器中访问http://localhost:7001/consumer/hello?a=1,快速多点几次,看到系统正忙,请稍后重试。限流规则已生效。上面的限流处理和controller在同一个类中, @SentinelResource可以不要blockHandlerClass属性。

 

修改:

@RequestMapping("/hello")
@SentinelResource(value = "HelloConsumer-hello", blockHandler = "helloHandle", blockHandlerClass = HelloHanldeErr.class)
public String  hello(@RequestParam(value = "a") String a) {
    int i = 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后,在Sentinel dashboard中配置流控规则:
 

 

在浏览器中访问一次http://localhost:7001/consumer/hello?a=1,此时没有限流,看到:
 

 

在浏览器中快速访问http://localhost:7001/consumer/hello?a=1,发生限流后,看到系统正忙,请稍后重试。可知blockHandler是处理限流,不处理出现异常

 

接下来看fallback属性:

@RequestMapping("/helloEx")
@SentinelResource(value = "HelloConsumer-helloEx", fallback = "helloBack", fallbackClass = HelloHanldeErr.class)
public String  helloEx(@RequestParam(value = "a") String a) {
    return "hello,Consumer,port:" + port;
}

@Slf4j
public class HelloHanldeErr {

    public static String helloHandle(String a, BlockException e) {
        log.error("被限流",e);
        return "系统正忙,请稍后重试";
    }


    public static String helloBack(String a, Throwable e) {
        log.error("出错", e);
        return "系统出错";
    }
}

在Sentinel dashboard配置流控规则:
 

 

在浏览器中快速访问http://localhost:7001/consumer/helloEx?a=1,发生限流时看到系统出错

 

修改:

@RequestMapping("/helloEx")
@SentinelResource(value = "HelloConsumer-helloEx", fallback = "helloBack", fallbackClass = HelloHanldeErr.class)
public String  helloEx(@RequestParam(value = "a") String a) {
    int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启,不在Sentinel dashboard 中配置限流规则。访问http://localhost:7001/consumer/helloEx?a=1,看到系统出错。可知fallback是处理出错或限流

 

修改:

@RequestMapping("/helloEx")
@SentinelResource(value = "HelloConsumer-helloEx", fallback = "helloBack", fallbackClass = HelloHanldeErr.class,blockHandler = "helloHandle", blockHandlerClass = HelloHanldeErr.class)
public String  helloEx(@RequestParam(value = "a") String a) {
  //  int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后在sentinel dashboard中配置限流规则:
 

 

快速访问http://localhost:7001/consumer/helloEx?a=1,发生限流时,可看到系统正忙,请稍后重试

 

修改:

@RequestMapping("/helloEx")
@SentinelResource(value = "HelloConsumer-helloEx", fallback = "helloBack", fallbackClass = HelloHanldeErr.class,blockHandler = "helloHandle", blockHandlerClass = HelloHanldeErr.class)
public String  helloEx(@RequestParam(value = "a") String a) {
    int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后在Sentinel dashboard中配置流控规则:
 

 

访问一次http://localhost:7001/consumer/helloEx?a=1,此时没有限流,看到系统出错。快速访问http://localhost:7001/consumer/helloEx?a=1,发生限流时,看到系统正忙,请稍后重试。可知同时配置fallback和blockHandler时,fallback处理异常,blockHandler处理限流

 

最后看下defaultFallback:

@RequestMapping("/helloDefaultEx")
@SentinelResource(value = "HelloConsumer-helloDefaultEx", defaultFallback = "helloDefaultBack", fallbackClass = HelloHanldeErr.class)
public String  helloDefaultEx(@RequestParam(value = "a") String a) {
  //  int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

@Slf4j
public class HelloHanldeErr {

    public static String helloHandle(String a, BlockException e) {
        log.error("被限流",e);
        return "系统正忙,请稍后重试";
    }


    public static String helloBack(String a, Throwable e) {
        log.error("出错", e);
        return "系统出错";
    }

    public static String helloDefaultBack(Throwable e) {
        log.error("出错", e);
        return "默认...系统出错";
    }
}

在Sentinel dashboard中配置流控规则:
 

 

在浏览器中快速访问http://localhost:7001/consumer/helloDefaultEx?a=1,发生限流时,看到默认...系统出错,可知defaultFallback可以处理限流

 

修改为:

@RequestMapping("/helloDefaultEx")
@SentinelResource(value = "HelloConsumer-helloDefaultEx", defaultFallback = "helloDefaultBack", fallbackClass = HelloHanldeErr.class)
public String  helloDefaultEx(@RequestParam(value = "a") String a) {
    int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后,不匹配流控规则,在浏览器中访问http://localhost:7001/consumer/helloDefaultEx?a=1,看到默认...系统出错,可知defaultFallback可以处理异常

 

修改为:

@RequestMapping("/helloDefaultEx")
@SentinelResource(value = "HelloConsumer-helloDefaultEx", defaultFallback = "helloDefaultBack", fallbackClass = HelloHanldeErr.class, exceptionsToIgnore = ArithmeticException.class)
public String  helloDefaultEx(@RequestParam(value = "a") String a) {
    int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后,不匹配流控规则,在浏览器中访问http://localhost:7001/consumer/helloDefaultEx?a=1,看到:
 

 

当出现的异常出现在exceptionsToIgnore属性中,defaultFallback就不能处理异常。

 

修改为:

@RequestMapping("/helloDefaultEx")
@SentinelResource(value = "HelloConsumer-helloDefaultEx", defaultFallback = "helloDefaultBack", fallback = "helloBack", fallbackClass = HelloHanldeErr.class)
public String  helloDefaultEx(@RequestParam(value = "a") String a) {
    int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后,不匹配流控规则,在浏览器中访问http://localhost:7001/consumer/helloDefaultEx?a=1,看到系统出错,可知fallback和defaultFallback同时出现优先使用fallback

 

修改为:

@RequestMapping("/helloDefaultEx")
@SentinelResource(value = "HelloConsumer-helloDefaultEx", defaultFallback = "helloDefaultBack", fallback = "helloBack", fallbackClass = HelloHanldeErr.class, exceptionsToIgnore = ArithmeticException.class)
public String  helloDefaultEx(@RequestParam(value = "a") String a) {
    int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后,不匹配流控规则,在浏览器中访问http://localhost:7001/consumer/helloDefaultEx?a=1,看到:
 

 

当出现的异常出现在exceptionsToIgnore属性中,fallback就不能处理异常。

 

修改为

@RequestMapping("/helloDefaultEx")
@SentinelResource(value = "HelloConsumer-helloDefaultEx", defaultFallback = "helloDefaultBack",  fallbackClass = HelloHanldeErr.class, blockHandler = "helloHandle", blockHandlerClass = HelloHanldeErr.class)
public String  helloDefaultEx(@RequestParam(value = "a") String a) {
   // int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后在Sentinel dashboard中配置流控规则:
 

 

在浏览器中快速访问http://localhost:7001/consumer/helloDefaultEx?a=1,出现限流时,看到系统正忙,请稍后重试。可知defaultFallback和blockHandler同时出现,出现限流时优先使用blockHandler

 

修改为

@RequestMapping("/helloDefaultEx")
@SentinelResource(value = "HelloConsumer-helloDefaultEx", defaultFallback = "helloDefaultBack",  fallbackClass = HelloHanldeErr.class, blockHandler = "helloHandle", blockHandlerClass = HelloHanldeErr.class)
public String  helloDefaultEx(@RequestParam(value = "a") String a) {
    int i= 10 / 0;
    return "hello,Consumer,port:" + port;
}

重启后在Sentinel dashboard中配置流控规则:
 

 

在浏览器中快速访问http://localhost:7001/consumer/helloDefaultEx?a=1,出现限流时,看到系统正忙,请稍后重试。只访问一次,没有限流,出现异常,看到默认...系统出错。可知defaultFallback和blockHandler同时出现,出现限流时优先使用blockHandler,defaultFallback处理异常

标签:String,helloDefaultEx,十三,SentinelResource,value,限流,fallback,port
From: https://www.cnblogs.com/shigongp/p/17529903.html

相关文章

  • 第十三周
    1、编写一个程序,实现从命令行参数输入两//个字符串类型的数值,并计算输出两个数值的//和。[必做题]package one;import java.util.Scanner;public class one{public static void main(String[]args){// TODO Auto-generatedmethodstu//1、编写一个程序,实......
  • 操作系统权限提升(十三)之绕过UAC提权-MSF和CS绕过UAC提权
    系列文章操作系统权限提升(十二)之绕过UAC提权-WindowsUAC概述注:阅读本编文章前,请先阅读系列文章,以免造成看不懂的情况!!MSF和CS绕过UAC提权CS绕过UAC提权拿到一个普通管理员的SHELL,在CS中没有*号代表有UAC执行添加用户的命令时显示拒绝访问使用CS自带的插件进行绕过提权直接提到......
  • 【十三】JavaScript之DOM
    【十三】JavaScript之DOM【1】DOMDOM(DocumentObjectModel,译作文档对象模型),这部分内容主要是学习document对象提供给开发者操作html/xml文档的方法属性或子对象来完成动态特效的。当然这部分代码在不同浏览器下的效果几乎一样,除了IE。元素操作[元素的获取,元素的属性......
  • JavaCV的摄像头实战之十三:年龄检测
    欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos本篇概览本文是《JavaCV的摄像头实战》系列的第十三篇,前文《JavaCV的摄像头实战之十二:性别检测》中,借助训练好的卷积神经网络模型开发出了识别性别的应用,今天在前文基础......
  • 【十三】MySQL数据库之读现象与事务隔离机制
    【十三】MySQL数据库之读现象与事务隔离机制读现象与事务隔离机制【一】数据库读现象【1】读现象在本质上来说是数据库在高并发场景下多个同时执行的事务带来的影响。【2】数据库主要有三大常见的读现象:脏读:事务1和事务2并发执行事务1改了数据事务2读取了以后但事......
  • 软件测试|web自动化测试神器playwright教程(二十三)
    前言我们在进行web自动化时,经常遇到一些不好操作的元素,普通的元素定位和操作容易报错,如果我们使用的selenium的话,就可以使用selenium调用js脚本进行操作。在playwright中也有类似的方法,使用page.evaluate()执行JavaScript脚本。page.evaluate()和page.evaluate_handle()之间的唯......
  • 二十三、区块量化 TD指标
    #!/usr/bin/envpython#-*-coding:utf-8-*-importtalibimportcross_orderasorderimporttimedefTDSequential(close):tdlist=[0,0,0,0]#tdlist是存储TD结果用的,前4个无效用0占位置.因为TD定义是下标第n和n-4比较top=0#初始化上标bot=0#初......
  • 《无垠的太空(7).波斯波利斯崛起》太阳系征服战2(第二十三章:德鲁默)
    第二十三章:德鲁默  扩展阅读《无垠的太空(7).波斯波利斯崛起》速读:https://www.cnblogs.com/rockyching2009/p/16790702.html《无垠的太空(7).波斯波利斯崛起》合集:https://www.cnblogs.com/rockyching2009/category/2238049.html《无垠的太空(9).利维坦陨落》全集:https:/......
  • 天天打卡一小时第十三天
    天天打卡一小时第十三天问题描述3-3校园歌手大赛任务描述:8号选手参加校园歌手大赛,编程读入20个整数(70-100之间)并存入数组中做为20个评委的打分,请按题目要求编程实现输出样例要求的功能(最后得分为去掉最高分和最低分后的平均分)。输入格式:20个整数输出格式:见样例输入样例:82......
  • 代码随想录算法训练营第十三天| 层序遍历 226.翻转二叉树 (优先掌握递归) 101. 对
    层序遍历注意:1,使用队列的形式,依次入队,同时对队列进行计数2,知道数目消失,才进行下一个队列代码:1vector<vector<int>>levelOrder(TreeNode*root)2{3vector<vector<int>>result;4if(root==NULL)returnresult;5queue<TreeNode*>selected;6......