Sentinel提供了@SentinelResource注解用于定义资源,并提供可选的异常回退和Block回退。异常回退指的是@SentinelResource
注解标注的方法发生Java异常时的回退处理;Block回退指的是当@SentinelResource
资源访问不符合Sentinel控制台定义的规则时的回退(默认返回Blocked by Sentinel (flow limiting))。这节简单记录下该注解的用法。
框架搭建
使用IDEA创建一个maven项目,artifactId为spring-cloud-alibaba-sentinelresource,然后在其下面创建两个Module(Spring Boot项目),artifactId分别为consumer和provider,充当服务消费端和服务提供端,项目结构如下图所示:
spring-cloud-alibaba-sentinelresource的pom内容:
1 |
|
引入了spring-boot-starter-web和spring-cloud-alibaba-nacos-discovery Nacos服务注册发现依赖。
provider的pom的内容如下所示:
1 |
|
consumer的pom内容如下:
1 |
|
因为要演示在消费端使用@SentinelResource
注解,所以我们引入了spring-cloud-starter-alibaba-sentinel依赖。
provider的配置文件application.yml内容如下:
1 | server: |
配置了端口号,服务名和nacos地址。
consumer的配置文件application.yml内容如下:
1 | server: |
配置了端口号,服务名,nacos地址和sentinel控制台地址等。
基本用法
我们在provider下添加一个REST资源。在provider的cc.mrbird.provider目录下新建controller包,然后在该包下新建GoodsController
:
1 |
|
接着在consumer端通过Ribbon消费这个资源。在consumer的启动类ConsumerApplication
里注册RestTemplate
:
1 |
|
在consumer的cc.mrbird.consumer下新建controller包,然后在该包下新建BuyController
:
1 |
|
在buy
方法中,我们通过Ribbon的RestTemplate
访问provider的/goods/buy
接口。当count参数大于20或者name参数的值为miband的时候,方法将抛出异常。buy
方法上使用@SentinelResource
注解标注,标识为一个sentinel资源,资源名称为buy,并且配置了fallback方法和blockHandler方法。
如前面所说,当buy
方法本身抛出异常时,会进入fallback指定的回退方法中;当buy
方法调用不符合sentinel控制台规定的规则(如流控规则,降级规则等)时,会进入blockHander指定的block方法中。为了确保成功地进入回退方法(成功反射),它们必须满足以下规则:
- 函数访问范围需要是
public
; - Fallback函数,函数签名与原函数一致或末尾加一个
Throwable
类型的参数; - Block异常处理函数,参数最后多一个
BlockException
,其余与原函数一致。
启动provider、consumer、nacos和sentinel控制台,浏览器访问:http://localhost:9091/buy/ipad/2:
我们在sentinel控制台中添加如下流控规则:
QPS阈值为2。
然后快速访问http://localhost:9091/buy/ipad/2:
可以看到,当方法访问不符合sentinel控制台规则时,进入的是blockHandler指定的回退方法。
如果访问:http://localhost:9091/buy/ipad/21
或者:http://localhost:9091/buy/miband/2
方法自身抛出异常引发回退,进入的是fallback指定的回退方法。
其他属性
在当前类中编写回退方法会使得代码变得冗余耦合度高,我们可以将回退方法抽取出来到一个指定类中。
在cc.mrbird.consumer包下新建reveal包,然后在该包下新建BuyBlockHandler
:
1 | public class BuyBlockHandler { |
可以看到我们只是将buyBlock
方法挪到了BuyBlockHandler
中,不过这里的方法必须是static
的。
接着新建BuyFallBack
:
1 | public class BuyFallBack { |
这样BuyController
的代码就可以精简为:
1 |
|
fallbackClass
和blockHandlerClass
指定回退方法所在的类。
此外我们也可以当遇到某个类型的异常时,不进行回退。比如:
1 |
|
exceptionsToIgnore
指定,当遇到空指针异常时,不回退。
重启consumer,浏览器访问:http://localhost:9091/buy/miband/2:
可以看到,此次并没有进行回退,而是直接返回error page。
本节源码链接:https://github.com/wuyouzhuguli/SpringAll/tree/master/78.spring-cloud-alibaba-sentinelresource