首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

20分钟就带你透彻理解微服务高并发适配主流框架:注解切面

注解切面

资源可以是一个接口、一个方法或一段代码。除提供适配主流框架的模块外,Sentinel还支持使用“注解+切面”的方式将一个方法定义为资源,其实现原理与适配主流框架的实现原理大同小异。

使用注解定义资源虽然也很方便,但是依然需要修改代码,需要为每个资源加上注解,这是局部的,而使用适配模块是全局的,只要在项目中添加依赖配置就能生效,但是无法适配所有场景。

@SentinelResource注解用于定义资源,作为切点,可被注释在方法或类上。该注解的源码如下:

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模块的依赖,配置如下:

Sentinel使用AspectJ框架实现切面,切面类为SentinelResourceAspect,如果是在SpringBoot项目中使用sentinel-annotation-aspectj模块,则只需要将SentinelResourceAspect切面类注入Spring容器即可,代码如下:

SentinelResourceAspect切面类的源码如下:

调用SphU#entry方法。

处理BlockException,如果注解配置了blockHandlerClass和blockHandler,则使用反射调用BlockException处理器方法。

处理执行资源方法抛出的异常,根据exceptionsToIgnore和exceptionsToTrace配置项决定是否将此异常统计到异常指标中。

调用Entry#exit方法。

SentinelResourceAspect#invokeResourceWithSentinel方法中调用的handleBlockException方法与handleFallback方法的实现相同,都是通过处理器的类型、方法名、方法参数使用反射从BlockException处理器或Fallback处理器中获取方法的Method实例调用,并且要求:

如果未配置处理器类型或者配置的处理器类型是当前拦截方法所属类,则从当前拦截方法所属类中寻找方法,否则从指定处理器类型中寻找方法,但要求方法是一个静态方法。

方法的参数类型与拦截方法的参数类型相匹配,并且多出一个接收异常的参数。

如果资源方法的方法描述符为:

则blockHandler方法的方法描述符必须匹配:

fallback方法的方法描述符必须匹配:

@SentinelResource注解支持注释在类或方法上,如果是注释在类上,且通过value属性指定了资源名称,则该类下的所有public方法都会被切面拦截,并且都会被当作同一个资源处理,而如果未通过value属性指定资源名称,则自动根据类名、方法名称和方法参数生成资源名称,代码如下:

显然,这样的资源名称非常不便于进行规则配置,因此在使用@SentinelResource注解时最好自行定义资源名称。

除了使用sentinel-annotation-aspectj模块支持@SentinelResource注解,也可以自行实现切面类,指定全局BlockException处理器和Fallback处理器,而不必在同一个项目中为每个@SentinelResource注解都配置BlockException处理器和Fallback处理器,并且重写切面的实现也比较简单。

本文给大家讲解的内容是深度解析微服务高并发适配主流框架:注解切面

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230404A00OI200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券