转载声明 : 该文章出处为 扛麻袋的少年
接上一篇文章:Spring Cloud Alibaba Sentinel 流控、降级、热点、系统规则详解。了解完 Sentinel 流控、降级、热点、系统规则后,本文 来聊聊 @SentinelResource 注解的使用
@SentinelResource 可以说是 Sentinel 学习的突破口,搞懂了这个注解的应用,基本上就搞清楚了 Sentinel 的大部分应用场景。Sentinel 提供了 @SentinelResource 注解用于定义资源,并提供了AspectJ的扩展用于自动定义资源、处理BlockException等。
(红色标注属性为常用属性)
属性名是否必填说明value是资源名称 。(必填项,需要通过 value 值找到对应的规则进行配置)entryType否entry类型,标记流量的方向,取值IN/OUT,默认是OUTblockHandler否处理BlockException的函数名称(可以理解为对Sentinel的配置进行方法兜底)。函数要求:1.必须是 public 修饰2.返回类型与原方法一致3. 参数类型需要和原方法相匹配,并在最后加 BlockException 类型的参数。4. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 blockHandlerClass ,并指定blockHandlerClass里面的方法。blockHandlerClass 否存放blockHandler的类。对应的处理函数必须 public static 修饰,否则无法解析,其他要求:同blockHandler。fallback否用于在抛出异常的时候提供fallback处理逻辑(可以理解为对Java异常情况方法兜底)。fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。函数要求:1.返回类型与原方法一致2.参数类型需要和原方法相匹配,Sentinel 1.6开始,也可在方法最后加 Throwable 类型的参数。3.默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定fallbackClass里面的方法。fallbackClass否存放fallback的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同fallback。defaultFallback否用于通用的 fallback 逻辑。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,以fallback为准。函数要求:1.返回类型与原方法一致2.方法参数列表为空,或者有一个 Throwable 类型的参数。3.默认需要和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定 fallbackClass 里面的方法。exceptionsToIgnore否指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。exceptionsToTrace否需要trace的异常fallback只用来处理与Java逻辑异常相关的兜底。比如:NullPointerException、ArrayIndexOutOfBoundsException 等Java代码中的异常,fallback 指定的兜底方法便会生效。
2.1 兜底方法与业务方法耦合
@GetMapping("/testA") @SentinelResource(value = "testA", fallback = "fallbackMethod") public String testA() { int i = 10 / 0; return "-----testA"; } public String fallbackMethod(Throwable e) { return "限流请求连接(Java类异常)的兜底方法:" + e.getMessage(); }2.2 使用 fallbackClass 将兜底方法与业务解耦合
/** * 业务逻辑 */ @GetMapping("/testA") @SentinelResource(value = "testA", fallback = "fallbackMethod", fallbackClass = CustomerFallback.class) public String testA() { int i = 10 / 0; return "-----testA"; } /** * 单独一个类,存放兜底方法 */ public class CustomerFallback { public static String fallbackMethod(Throwable e) { return "限流请求连接(Java类异常)的兜底方法:" + e.getMessage(); } }2.3 兜底结果返回:
blockHandler 只用来处理 与 Sentinel 配置有关的兜底。比如:配置某资源 QPS =1,当 QPS >1 时,blockHandler 指定的兜底方法便会生效。
3.1 兜底方法与业务方法耦合.
/** * 业务逻辑 */ @GetMapping("/testB") @SentinelResource(value = "testB",blockHandler = "exceptionMethod") public String testB() { return "-----testB"; } public String exceptionMethod(BlockException exception) { return "限流@SentinelResource value 属性的兜底方法:" + exception; }3.2 使用 fallbackClass 将兜底方法与业务解耦合
@GetMapping("/testB") @SentinelResource(value = "testB",blockHandler = "exceptionMethod",blockHandlerClass = CustomerBlockHandler.class) public String testB() { return "-----testB"; } /** * 单独一个类,存放兜底方法 */ public class CustomerBlockHandler { public static String exceptionMethod(BlockException exception) { return "处理与 Sentinel 配置相关的兜底方法:" + exception; } }3.3 兜底结果返回
使用 exceptionsTolgnore 属性,来 指定某些异常不执行兜底方法,直接显示错误信息。配置 ArithmeticException 异常不走兜底方法。java.lang.ArithmeticException: / by zero ,便不会再执行兜底方法,直接显示错误信息给前台页面。
@GetMapping("/testA") @SentinelResource(value = "testA", fallback = "fallbackMethod", fallbackClass = CustomerFallback.class, exceptionsToIgnore = ArithmeticException.class) public String testA() { int i = 10 / 0; return "-----testA"; }不走兜底方法,直接返回异常到页面:
使用 defaultFallback 来指定通用的 fallback 兜底方法。
如果当前业务配置有 defaultFallback 和 fallback 两个属性,则优先执行 fallback 指定的方法。如果 fallback 指定的方法不存在,还会执行 defaultFallback 指定的方法。 /** * 业务逻辑 */ @GetMapping("/testA") @SentinelResource(value = "testA", fallback = "fallbackMethod", fallbackClass = CustomerFallback.class, defaultFallback = "defaultFallbackMethod" //直接指定即可,使用比较简单 ) public String testA() { int i = 10 / 0; return "-----testA"; } /** * 单独一个类,存放兜底方法 */ public class CustomerFallback { public static String defaultFallbackMethod(Throwable e) { return "通用的fallback兜底方法"; } public static String fallbackMethod(Throwable e) { return "限流请求连接(Java类异常)的兜底方法:" + e.getMessage(); } }本文代码不提供,将文中业务代码配合如下代码使用即可。下载地址:Spring Cloud Alibaba Sentinel 简单使用 (提取码:nfmb)
下一篇:Sentinel 已配置规则持久化问题