天天看點

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

作者:程式員進階碼農II

注解切面

資源可以是一個接口、一個方法或一段代碼。除提供适配主流架構的子產品外,Sentinel還支援使用“注解+切面”的方式将一個方法定義為資源,其實作原理與适配主流架構的實作原理大同小異。

使用注解定義資源雖然也很友善,但是依然需要修改代碼,需要為每個資源加上注解,這是局部的,而使用适配子產品是全局的,隻要在項目中添加依賴配置就能生效,但是無法适配所有場景。

@SentinelResource

@SentinelResource注解用于定義資源,作為切點,可被注釋在方法或類上。該注解的源碼如下。

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

• value:配置資源名稱。

• entryType:配置流量類型(IN/OUT)。

• resourceType:配置資源類型,如COMMON_WEB、COMMON_RPC。

• blockHandlerClass:配置BlockException處理器的類型。

• blockHandler:需要與blockHandlerClass組合使用,配置BlockException處理器的方法名稱。

• fallbackClass:配置Fallback處理器的類型。

•fallback:配置fallback方法名稱,需要與fallbackClass組合使用,提供類似于适配OpenFeign架構的失敗回退機制,可用于限流、熔斷後的降級處理。

• exceptionsToTrace:指定隻追蹤哪些類型的異常,不配置會導緻Sentinel不統計異常名額資料,預設追蹤所有類型的異常。

• exceptionsToIgnore:與exceptionsToTrace正好相反,指定不追蹤哪些類型的異常。

被exceptionsToIgnore方法包含的異常不僅不會被Sentinel統計到異常名額中,也不會調用Fallback處理器處理降級,而被exceptionsToTrace方法包含的異常才會被Sentinel統計到異常名額中,并且調用Fallback處理器處理降級。

@SentinelResource注解隻是切點,每個配置項的具體用途還需要從切面類中尋找答案。

SentinelResourceAspect

Sentinel在sentinel-annotation-aspectj子產品中實作對@SentinelResource注解的支援,是以,要使@SentinelResource注解生效,需要在項目中添加sentinel-annotation-aspectj子產品的依賴,配置如下。

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

Sentinel使用AspectJ架構實作切面,切面類為SentinelResourceAspect,如果是在SpringBoot項目中使用sentinel-annotation-aspectj子產品,則隻需要将SentinelResourceAspect切面類注入Spring容器即可,代碼如下。

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

SentinelResourceAspect切面類的源碼如下。

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

① 擷取@SentinelResource注解,從注解中取得資源名稱、流量類型和資源類型。

② 調用SphU#entry方法。

③ 處理BlockException,如果注解配置了blockHandlerClass和blockHandler,則使用反射調用BlockException處理器方法。

④ 處理執行資源方法抛出的異常,根據exceptionsToIgnore和exceptionsToTrace配置項決定是否将此異常統計到異常名額中。

⑤ 調用Entry#exit方法。

SentinelResourceAspect#invokeResourceWithSentinel方法中調用的handleBlockException方法與handleFallback方法的實作相同,都是通過處理器的類型、方法名、方法參數使用反射從BlockException處理器或Fallback處理器中擷取方法的Method執行個體調用,并且要求:

• 如果未配置處理器類型或者配置的處理器類型是目前攔截方法所屬類,則從目前攔截方法所屬類中尋找方法,否則從指定處理器類型中尋找方法,但要求方法是一個靜态方法。

• 方法的參數類型與攔截方法的參數類型相比對,并且多出一個接收異常的參數。

如果資源方法的方法描述符為:

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

則blockHandler方法的方法描述符必須比對:

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

fallback方法的方法描述符必須比對:

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

@SentinelResource注解支援注釋在類或方法上,如果是注釋在類上,且通過value屬性指定了資源名稱,則該類下的所有public方法都會被切面攔截,并且都會被當作同一個資源處理,而如果未通過value屬性指定資源名稱,則自動根據類名、方法名稱和方法參數生成資源名稱,代碼如下。

20分鐘就帶你透徹了解微服務高并發适配主流架構:注解切面

顯然,這樣的資源名稱非常不便于進行規則配置,是以在使用@SentinelResource注解時最好自行定義資源名稱。

除了使用sentinel-annotation-aspectj子產品支援@SentinelResource注解,也可以自行實作切面類,指定全局BlockException處理器和Fallback處理器,而不必在同一個項目中為每個@SentinelResource注解都配置BlockException處理器和Fallback處理器,并且重寫切面的實作也比較簡單。

本文給大家講解的内容是深度解析微服務高并發适配主流架構:注解切面

  • 下篇文章給大家講解的内容是深度解析微服務高并發熱點參數限流:熱點參數限流功能的實作

繼續閱讀