@SentinelResource 注解
Sentinel 提供了 @SentinelResource
注解用于定义资源,并提供了 AspectJ (切面)的扩展用于自动定义资源、处理 BlockException
等。
注意:注解方式埋点不支持 private 方法。
@SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource
注解包含以下属性:
-
value
:资源名称,必需项(不能为空) -
entryType
:entry 类型,可选项(默认为EntryType.OUT
)资源调用的流量类型,是入口流量(
EntryType.IN
)还是出口流量(EntryType.OUT
),注意系统规则只对 IN 生效/** * @return the entry type (inbound or outbound), outbound by default */ EntryType entryType() default EntryType.OUT;
为了验证,添加如下两个接口,并配置系统入口流量限流规则:
@GetMapping("/out") @SentinelResource(value = "entryTypeOut", entryType = EntryType.OUT) public String entryTypeOut() { return "sentinelResource-out"; } @GetMapping("/in") @SentinelResource(value = "entryTypeIn", entryType = EntryType.IN) public String entryTypeIn() { return "sentinelResource-in"; }
新增系统规则:
此时查看实时监控面板,可以看出/in的通过的QPS为1,/out的入口通过的QPS为2,所以系统规则对/in是生效的
-
blockHandler
/blockHandlerClass
:blockHandler
对应处理BlockException
的函数名称,可选项。blockHandler 函数访问范围需要是public
,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException
。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。 -
fallback
:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
-
返回值类型必须与原函数返回值类型一致;
-
方法参数列表需要和原函数一致,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。@GetMapping("/fallback/{id}") //添加SentinelResource注解的fallback属性,同时设置方法来解决Java异常 @SentinelResource(value = "fallback", fallback = "fallbackHandler") public String fallback(@PathVariable Long id){ return "success"; } //保证方法签名与原方法一致或加一个 Throwable 类型的参数 public String fallbackHandler(Long id, Throwable e) { xxxxx } // 或者 public String fallbackHandler(Long id) { xxxxx }
-
fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。
-
-
defaultFallback
(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:-
返回值类型必须与原函数返回值类型一致;
-
方法参数列表需要为空,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。public String defaultFallbackHandle(Throwable ex){ xxxxx } // 或者 public String defaultFallbackHandle(){ xxxxx }
-
defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。
-
-
exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
注:1.6.0 之前的版本 fallback 函数只针对降级异常(
DegradeException
)进行处理,不能针对业务异常进行处理。
特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException
时只会进入 blockHandler
处理逻辑。若未配置 blockHandler
、fallback
和 defaultFallback
,则被限流降级时会将 BlockException
直接抛出。
自定义限流处理逻辑
其实我们在使用@SentinelResource注解这两种方案的时候,会出现一些问题:
- 没有体现我们自己的业务要求。
- 自定义处理方法和业务代码耦合在一起。
- 每个业务方法都添加一个限流处理方法,代码将会加剧膨胀。
- 无法实现统一全局处理。
解决:@SentinelResource除了blockHandler可以设置自定义限流处理逻辑方法以外,还提供另外一个属性来设置限流处理逻辑类型blockHandlerClass属性,此属性中设置的方法必需为 static 函数,否则无法解析。
具体逻辑
第一步
创建CustomerBlockHandler类型用于处理自定义限流处理逻辑,首先创建myhandler.CustomerBlockHandler
/**
* 此类型用来处理限流自定义逻辑
*/
public class CustomerBlockHandler {
public static String handlerException1(BlockException exception){
return "handlerException1:系统异常,请稍后重试!";
}
public static String handlerException2(BlockException exception){
return "handlerException2:网络崩溃了,请稍后重试!";
}
}
第二步
我们在SentinelResourceTestController类型中添加一个接口方法,同时设置@SentinelResource注解和blockHandlerClass属性对应的类型和这个类型中对应的处理方法
/**
* 此方法用到了自定义限流处理类型CustomerBlockHandler
* 中的handlerException1方法来处理限流逻辑。
*/
@GetMapping("/byCustomer")
@SentinelResource(value = "byCustomer",
blockHandlerClass = CustomerBlockHandler.class,
blockHandler = "handlerException1")
public String byCustomer(){
return "-----byCustomer";
}
第三步
测试:给byCustomer资源添加限流规则,然后来测试在超过限流阈值时处理方法是否为CustomerBlockHandler中handlerException1来进行处理。
流控效果:
fallback函数
(定义如上)
注意: fallback属性和blockHandler属性的本质不同在于他们作用的异常不同
- blockHandler:针对违反Sentinel控制台配置规则时触发BlockException异常时对应处理的属性
- fallback:针对Java本身出现的异常进行处理的对应属性。
@GetMapping("/fallback/{id}")
//添加SentinelResource注解的fallback属性,同时设置方法来解决Java异常
@SentinelResource(value = "fallback", fallback = "fallbackHandler")
public String fallback(@PathVariable Long id){
if (id < 0 || id > 3) {
throw new NullPointerException("无对应的记录");
}
return "success";
}
//保证方法签名与原方法一致或加一个 Throwable 类型的参数
public String fallbackHandler(Long id, Throwable e) {
return "出现未知的记录";
}
效果(未加流控规则前):
然后,我们添加流控规则:
F5刷新,这时地效果为:
总结:
fallback定义的函数方法,抛出了任何异常,都会触发指定函数的执行。(除了exceptionsToIgnore 里面排除掉的异常类型)
在触发定义的流控规则后,Sentinel会自动抛出BlockException异常。只有fallback存在,没有定义blockHandler时,此时也会触发fallback定义的函数方法。
同时配置blockHandler和fallback属性
@GetMapping("/fallback/{id}")
//同时添加SentinelResource注解的fallback和blockHandler属性 exceptionsToIgnore被标注的异常将会被 原样抛出
@SentinelResource(value = "falllback", fallback = "fallbackHandler", blockHandler = "blockHandler", exceptionsToIgnore = {ArrayIndexOutOfBoundsException.class})
public String fallback(@PathVariable Long id){
if (id < 0 || id > 3) {
throw new NullPointerException("无对应的记录");
}
return "success";
}
//保证方法签名与原方法一致或加一个 Throwable 类型的参数
public String fallbackHandler(Long id, Throwable e) {
return "出现未知的记录";
}
//处理Sentinel限流
public String blockHandler(Long id, BlockException e){
return "BlockException限流";
}
添加流控规则:
- 在没有触发流控规则之前的异常交给fallback来处理
- 但是一旦触发流控规则就变成了blockHandler来处理
exceptionsToIgnore属性
exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
修改代码:文章来源:https://www.toymoban.com/news/detail-548547.html
@GetMapping("/fallback/{id}")
//同时添加SentinelResource注解的fallback和blockHandler属性 exceptionsToIgnore被标注的异常将会被 原样抛出
@SentinelResource(value = "falllback", fallback = "fallbackHandler", blockHandler = "blockHandler", exceptionsToIgnore = {NullPointerException.class})
public String fallback(@PathVariable Long id){
if (id < 0 || id > 3) {
throw new NullPointerException("无对应的记录");
}
return "success";
}
效果:
文章来源地址https://www.toymoban.com/news/detail-548547.html
到了这里,关于七、Sentinel的注解@SentinelResource详细介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!