在前面的博客中,我給大家演示了使用 @SentinelResource 定義資源完成限流的例子好渠,下面就從源碼解析昨稼,看下SentinelResource是如何實(shí)現(xiàn)限流的。
@SentinelResource可以說是Sentinel學(xué)習(xí)的突破口拳锚,搞懂了這個(gè)注解的應(yīng)用假栓,基本上就搞清楚了 Sentinel 的大部分應(yīng)用場(chǎng)景。
一霍掺、@SentinelResource 解析
Sentinel 提供了 @SentinelResource 注解用于定義資源匾荆,并提供了 AspectJ 的擴(kuò)展用于自動(dòng)定義資源、處理 BlockException 等抗楔。
1棋凳、SentinelResource源碼
查看 Sentinel的源碼,可以看到 SentinelResource 定義了value,entryType,resourceType,blockHandler,fallback,defaultFallback等屬性连躏。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SentinelResource {
/**
* @return
*/
String value() default "";
/**
* @return the entry type (inbound or outbound), outbound by default
*/
EntryType entryType() default EntryType.OUT;
/**
* @return the classification (type) of the resource
* @since 1.7.0
*/
int resourceType() default 0;
/**
* @return name of the block exception function, empty by default
*/
String blockHandler() default "";
/**
* The {@code blockHandler} is located in the same class with the original method by default.
* However, if some methods share the same signature and intend to set the same block handler,
* then users can set the class where the block handler exists. Note that the block handler method
* must be static.
* @return the class where the block handler exists, should not provide more than one classes
*/
Class<?>[] blockHandlerClass() default {};
/**
* @return name of the fallback function, empty by default
*/
String fallback() default "";
/**
* The {@code defaultFallback} is used as the default universal fallback method.
* It should not accept any parameters, and the return type should be compatible
* @return name of the default fallback method, empty by default
* @since 1.6.0
*/
String defaultFallback() default "";
/**
* The {@code fallback} is located in the same class with the original method by default.
* However, if some methods share the same signature and intend to set the same fallback,
* then users can set the class where the fallback function exists. Note that the shared fallback method
* @return the class where the fallback method is located (only single class)
* @since 1.6.0
*/
Class<?>[] fallbackClass() default {};
/**
* @return the list of exception classes to trace, {@link Throwable} by default
* @since 1.5.1
*/
Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class};
/**
* Indicates the exceptions to be ignored. Note that {@code exceptionsToTrace} should
* not appear with {@code exceptionsToIgnore} at the same time, or {@code exceptionsToIgnore}
* will be of higher precedence.
*
* @return the list of exception classes to ignore, empty by default
* @since 1.6.0
*/
Class<? extends Throwable>[] exceptionsToIgnore() default {};
}
2剩岳、屬性說明
參考源碼的注釋,逐個(gè)解釋下這幾個(gè)屬性的作用入热。
value
資源名稱拍棕,必需項(xiàng),因?yàn)樾枰ㄟ^resource name找到對(duì)應(yīng)的規(guī)則勺良,這個(gè)是必須配置的绰播。
entryType
entry 類型,可選項(xiàng)尚困,有IN和OUT兩個(gè)選項(xiàng)蠢箩,默認(rèn)為 EntryType.OUT。
public enum EntryType {
IN("IN"),
OUT("OUT");
}
blockHandler
blockHandler 對(duì)應(yīng)處理 BlockException 的函數(shù)名稱,可選項(xiàng)谬泌。
blockHandler 函數(shù)訪問范圍需要是 public滔韵,返回類型需要與原方法相匹配,參數(shù)類型需要和原方法相匹配并且最后加一個(gè)額外的參數(shù)掌实,類型為 BlockException陪蜻。
blockHandlerClass
blockHandler 函數(shù)默認(rèn)需要和原方法在同一個(gè)類中,如果希望使用其他類的函數(shù)贱鼻,則需要指定 blockHandlerClass 為對(duì)應(yīng)的類的 Class 對(duì)象宴卖,注意對(duì)應(yīng)的函數(shù)必需為 static 函數(shù),否則無法解析邻悬。
fallback
fallback 函數(shù)名稱症昏,可選項(xiàng),用于在拋出異常的時(shí)候提供 fallback 處理邏輯拘悦。fallback 函數(shù)可以針對(duì)所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進(jìn)行處理齿兔。
fallbackClass
fallbackClass的應(yīng)用和blockHandlerClass類似,fallback 函數(shù)默認(rèn)需要和原方法在同一個(gè)類中础米。
若希望使用其他類的函數(shù)分苇,則可以指定 fallbackClass 為對(duì)應(yīng)的類的 Class 對(duì)象,注意對(duì)應(yīng)的函數(shù)必需為 static 函數(shù)屁桑,否則無法解析医寿。
defaultFallback(since 1.6.0)
如果沒有配置defaultFallback方法,默認(rèn)都會(huì)走到這里來蘑斧。
默認(rèn)的 fallback 函數(shù)名稱靖秩,可選項(xiàng),通常用于通用的 fallback 邏輯竖瘾。
默認(rèn) fallback 函數(shù)可以針對(duì)所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進(jìn)行處理沟突。若同時(shí)配置了 fallback 和 defaultFallback,則只有 fallback 會(huì)生效捕传。
exceptionsToIgnore(since 1.6.0)
用于指定哪些異常被排除掉惠拭,不會(huì)計(jì)入異常統(tǒng)計(jì)中,也不會(huì)進(jìn)入 fallback 邏輯中庸论,而是會(huì)原樣拋出职辅。
二、Sentinel切面配置
應(yīng)用 @SentinelResource 注解聂示,必須開啟對(duì)應(yīng)的切面域携,引入SentinelResourceAspect。
1鱼喉、AspectJ方式
Sentinel支持 AspectJ 的擴(kuò)展用于自動(dòng)定義資源秀鞭、處理 BlockException 等趋观,如果應(yīng)用中開啟了 AspectJ,那么需要在 aop.xml 文件中引入對(duì)應(yīng)的 Aspect:
<aspects>
<aspect name="com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect"/>
</aspects>
2气筋、Spring AOP 方式
如果應(yīng)用中使用了 Spring AOP拆内,需要在代碼中添加SentinelResourceAspect的Bean旋圆,通過配置的方式將 SentinelResourceAspect 注冊(cè)為一個(gè) Spring Bean:
@Configuration
public class SentinelAspectConfiguration {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
三宠默、總結(jié)
這節(jié)內(nèi)容學(xué)習(xí)了@SentinelResource的相關(guān)屬性,以及在項(xiàng)目中通過切面開啟SentinelResource的方式灵巧,不過為什么使用@SentinelResource必須開啟切面搀矫?
下一節(jié)就學(xué)習(xí)下 Sentinel中的 SentinelResourceAspect 切面原理。