文章目录
前言
学习@SentinelResource注解,如何处理限流后的请求?如何处理资源方法发生异常后的事情?
第一节 @SentinelResource的源码解析
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SentinelResource {
String value() default "";
EntryType entryType() default EntryType.OUT;
int resourceType() default 0;
String blockHandler() default "";
Class<?>[] blockHandlerClass() default {};
String fallback() default "";
String defaultFallback() default "";
Class<?>[] fallbackClass() default {};
Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class};
Class<? extends Throwable>[] exceptionsToIgnore() default {};
}
第二节 blockHandler和fallback
1. 如何使用blockHandler和fallback
- 编写demo,实现了blockHandler指定的方法和fallback的方法
@Service
@Slf4j
public class MySourceServiceImpl {
/**
* 定义一个资源<br>
* 定义当资源内部发生异常的时候的处理逻辑<br>
* blockHandler 定义当资源内部发生了BlockException应该进入的方法,捕获的是Sentinel定义的异常<br>
* fallback 定义当资源内部发生了Throwable应该进入的方法
* @param name
* @return
*/
@SentinelResource(value="findById",blockHandler = "blockHandler11",fallback = "fallback2")//定义资源
public String findById(String name){
log.info("查询处理");
return "abc";
}
/**
* blockHanler要求<br>
* 1. 当前方法的返回值和参数必须与原方法保持一致<br>
* 2. 允许在参数列表的最后加入一个参数BlockException,用来接受原方法中发生的异常
* @param name
* @param e
* @return
*/
public String blockHandler11(String name, BlockException e){
log.error("发生BlockException时,被运行了");
return "BlockException";
}
/**
* fallback2<br>
* 1. 当前方法的返回值和参数必须与原方法保持一致<br>
* 2. 允许在参数列表的最后加入一个参数Throwable,用来接受原方法中发生的异常
* @param name
* @param e
* @return
*/
public String fallback2(String name, Throwable e){
log.error("发生Throwable时,被运行了");
return "Throwable";
}
}
启动服务器测试,并设置流控规则
频繁请求接口,发现因为限流进入了blockHandler 设定的方法。也就是说因为限流规则,不能进入资源方法内时,请求会进入到blockHandler定义的方法。
把blockHandler对应的方法去掉,再次执行时,限制流后进入fallback指定的方法
如果资源方法内发生异常,也会之间进入fallback方法内
2. 总结
- 方法提必须是public
- 返回值类型和参数需要与资源方法一致。blockHandler可以在参数最后一列添加一个BlockException,而fallback可以在参数最后一列添加一个Throwable
- blockHandler 指定的方法,当sentinel对资源发生限流时,限流后的请求将会进入blockHandler映射的方法。
- fallbck 指定的方法,当没有指定blockHandler时,fallback会接管限流过来的请求。如果资源方法运行时发生未捕获的异常,异常后会进入fallback方法;但是如果blockHandler运行发生异常,fallback并不会接管,除非blockerHandler未定义或者仅仅在@SentinelResource中声明了blockHandler,但是并没有并没有这个方法。
- 企业开发中,很多时候为了方便会直接定义fallback,而不会定义blockHandler
第三节 blockHandlerClass和fallbackClass
1. 如何使用blockHandlerClass和fallbackClass
通过源码,可以发现@SentinelResource包含了blockHandlerClass和fallbackClass方法
,怎么使用呢?
- 使用规则:
blockHandlerClass和blockHandler需要一起使用,blockHandlerClass指定类,blockHandler指定方法名,并且方法需要声明为static静态方法。
fallbackClass和fallback需要一起使用,fallbackClass指定类,fallback指定方法名,并且方法需要声明为static静态方法。
示例可见下图。
2. 总结
blockHandlerClass和fallbackClass其实与第二节的内容一样,只不过声明blockHandlerClass和fallbackClass可以把blockHandler方和fallback方法单独声明在外部的类里面。
第四节 defaultFallback
与fallback使用一致。默认使用fallback处理,同时配置defaultFallback和fallback时,以fallback为准。
defaultFallback作为默认通用的处理逻辑。
本文含有隐藏内容,请 开通VIP 后查看