1. 程式人生 > >一個註解搞懂 Sentinel,@SentinelResource 總結

一個註解搞懂 Sentinel,@SentinelResource 總結

在前面的部落格中,我給大家演示了使用 @SentinelResource 定義資源完成限流的例子,
下面就從原始碼解析開始,看下SentinelResource是如何實現限流的,以及@SentinelResource提供了哪些功能,支援哪些屬性。

@SentinelResource可以說是Sentinel學習的突破口,搞懂了這個註解的應用,
基本上就搞清楚了 Sentinel 的大部分應用場景。

一、@SentinelResource 解析

Sentinel 提供了 @SentinelResource 註解用於定義資源,
並提供了 AspectJ 的擴充套件用於自動定義資源、處理 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、屬性說明

參考原始碼的註釋,逐個解釋下這幾個屬性的作用。

value

資源名稱,必需項,因為需要通過resource name找到對應的規則,這個是必須配置的。

entryType

entry 型別,可選項,
有IN和OUT兩個選項,預設為 EntryType.OUT。

public enum EntryType {
    IN("IN"),
    OUT("OUT");
}

blockHandler

blockHandler 對應處理 BlockException 的函式名稱,可選項。
blockHandler 函式訪問範圍需要是 public,返回型別需要與原方法相匹配,

引數型別需要和原方法相匹配並且最後加一個額外的引數,型別為 BlockException。

blockHandlerClass

blockHandler 函式預設需要和原方法在同一個類中,如果希望使用其他類的函式,
則需要指定 blockHandlerClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。

fallback

fallback 函式名稱,可選項,用於在丟擲異常的時候提供 fallback 處理邏輯。
fallback 函式可以針對所有型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。

fallbackClass

fallbackClass的應用和blockHandlerClass類似,fallback 函式預設需要和原方法在同一個類中。
若希望使用其他類的函式,則可以指定 fallbackClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。

defaultFallback(since 1.6.0)

如果沒有配置defaultFallback方法,預設都會走到這裡來。
預設的 fallback 函式名稱,可選項,通常用於通用的 fallback 邏輯。
預設 fallback 函式可以針對所有型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。
若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。

exceptionsToIgnore(since 1.6.0)

用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣丟擲。

二、Sentinel切面配置

應用 @SentinelResource 註解,必須開啟對應的切面,引入SentinelResourceAspect。

1、AspectJ方式

Sentinel支援 AspectJ 的擴充套件用於自動定義資源、處理 BlockException 等,
如果應用中開啟了 AspectJ,那麼需要在 aop.xml 檔案中引入對應的 Aspect:

<aspects>
    <aspect name="com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect"/>
</aspects>

2、Spring AOP 方式

如果應用中使用了 Spring AOP,需要在程式碼中新增SentinelResourceAspect的Bean,
通過配置的方式將 SentinelResourceAspect 註冊為一個 Spring Bean:

@Configuration
public class SentinelAspectConfiguration {

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}

三、總結

這節內容學習了@SentinelResource的相關屬性,
以及在專案中通過切面開啟SentinelResource的方式,
不過為什麼使用@SentinelResource必須開啟切面?
下一節就學習下 Sentinel中的 SentinelResourceAspect 切面原理