3-CloudAlibaba-Sentinel
(@SentinelResource
注解)学习笔记2020.10.23
前言: (官网)
Hystrix
有@HystrixCommand
指定条件与降级方法来进行服务降级, 返回自定义信息。
Sentinel
类似的注解就是@SentinelResource
Sentinel
提供了@SentinelResource
注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理BlockException
等。使用 Sentinel Annotation AspectJ Extension 的时候需要引入以下依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>x.y.z</version>
</dependency>
spring-cloud-starter-alibaba-sentinel
依赖中已经包含了。 所以无需引入。
@SentinelResource
注解 (官网属性说明)
1.0 通过@SentinelResource
注解自定义限流/降级, 处理方法
在之前的学习笔记中, 触发了限流或者服务降级的时候, 系统返回的是默认提示信息
Blocked by Sentinel (flow limiting)
, 实际上我们都是需要自定义信息进行返回的。
Hystrix
中是通过@HystrixCommand
注解中的fallbackMethod
属性进行配置降级后调用降级方法进行返回客户端。下面进行配置
Sentinel
的自定义降级/限流, 备份方法。
1.1.1 在原有Sentinel
学习的应用中增加api
接口
@GetMapping("/testFallback")
@SentinelResource(value = "testFallback",blockHandler = "handleFallback")
public CommonResult testFallback()
{
return new CommonResult(HttpStatus.HTTP_OK,"正常通过限流测试OK",null);
}
public CommonResult handleFallback(BlockException exception)
{
return new CommonResult(429,exception.getClass().getCanonicalName()+"\t 服务不可用,被拒绝限流了");
}
@SentinelResource
中的value
属性可以自定义名称, 但一般与api
路径去掉/
一样,
blockHandler
就是类似@HystrixCommand
注解中的fallbackMethod
属性, 用于自定义后备方法。
1.1.2 进行配置流控规则并测试
这样配置完后, 发现代码耦合度太高了, 每个方法都需要配置一个
blockHandler
方法吗? 不符合程序复用思想。
Hystrix
是通过@DefaultProperties(defaultFallback = "xxx方法名")
来给整个类配置默认后备。下面进行配置
Sentinel
通用自定义信息返回。
1.1.3 通过@SentinelResource
注解中的blockHandlerClass
属性, 实现通用自定义后备消息。
blockHandler
函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。
1.1.4 自定义blockHandlerClass
通用消息返回类
public class GlobalBlockHandler {
/**
* 方法必须是静态的, 并注意返回值要与使用到全局的类型一致。
*
* @param exception
* @author: ZhiHao
* @date: 2020/10/23
*/
public static CommonResult globalHandleFallback(BlockException exception) {
return new CommonResult(429, "按客戶自定义,全局通用后备方法");
}
}
1.1.5 新增2个带@SentinelResource
注解的api
接口
使用注解属性
blockHandlerClass
指定类。使用注解属性
blockHandler
指定类中那个方法为后备方法。
@GetMapping("/testFallback1")
@SentinelResource(value = "testFallback1",
blockHandlerClass = GlobalBlockHandler.class,
blockHandler = "globalHandleFallback")
public CommonResult testFallback1() {
return new CommonResult(HttpStatus.HTTP_OK, "正常通过限流测试OK------1", null);
}
@GetMapping("/testFallback2")
@SentinelResource(value = "testFallback2",
blockHandlerClass = GlobalBlockHandler.class,
blockHandler = "globalHandleFallback")
public CommonResult testFallback2() {
return new CommonResult(HttpStatus.HTTP_OK, "正常通过限流测试OK------2", null);
}
1.1.6 进行配置测试
2.0 注解中的fallback
属性 (只管业务异常)
fallback
/fallbackClass
:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback
函数可以针对所有类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。只管业务异常。 而
blockHandler
管控制台配置规则的异常。
2.1.1 新增测试fallback
属性接口
@GetMapping("/testTrueFallback")
@SentinelResource(value = "testTrueFallback", fallback = "handleTrueFallback")
public CommonResult testFallback() {
//throw new RuntimeException("测试异常");
int i = 10/0;
return new CommonResult(HttpStatus.HTTP_OK, "正常响应", null);
}
/**
* 返回值类型必须与原函数返回值类型一致;
* 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
*
* @param exception
* @author: ZhiHao
* @date: 2020/10/23
*/
public CommonResult handleTrueFallback(Throwable exception) {
return new CommonResult(429, exception.getClass().getCanonicalName() + "\t 服务出现异常了");
}
2.2.2 进行测试
测试完毕, 发现的问题一样, 需要为每个方法都配置一个
fallback
吗? 那样代码耦合太高。解决方法也几乎一样。
2.2.3 通过@SentinelResource
注解中的fallbackClass
属性, 实现通用自定义异常后备消息。
使用注解属性
fallbackClass
指定类。使用注解属性
fallback
指定类中那个方法为异常后备方法。
@GetMapping("/testTrueFallback")
@SentinelResource(value = "testTrueFallback",
fallbackClass = GlobalFallbackHandler.class,
fallback = "globalFallbackHandler")
public CommonResult testFallback() {
throw new RuntimeException("测试异常");
//int i = 10/0;
//return new CommonResult(HttpStatus.HTTP_OK, "正常响应", null);
}
2.2.4 自定义fallbackClass
通用异常消息返回类
public class GlobalFallbackHandler {
/**
* 方法必须是静态的
*
* @param exception
* @author: ZhiHao
* @date: 2020/10/23
*/
public static CommonResult globalFallbackHandler(Throwable exception) {
return new CommonResult(500, "全局通用异常后备方法");
}
}
2.2.5 进行配置测试
页面测试结果:
{
"code": 500,
"message": "全局通用异常后备方法",
"data": null
}
同时还有个
defaultFallback
属性, 可选项,通常用于通用的fallback
逻辑。
exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
3.0 同时配置注解的blockHandler
属性 与fallback
3.1.1 api
接口
/**
* 同时配置管控制台规则blockHandler异常与业务fallback异常
*
* @return com.atguigu.springcloud.entities.CommonResult
* @author: ZhiHao
* @date: 2020/10/23
*/
@GetMapping("/testFallbackAndBlockHandler")
@SentinelResource(value = "testFallbackAndBlockHandler",
fallbackClass = GlobalFallbackHandler.class,
fallback = "globalFallbackHandler",
blockHandlerClass = GlobalBlockHandler.class,
blockHandler = "globalHandleFallback")
public CommonResult testFallbackAndBlockHandler() {
throw new RuntimeException("测试异常");
}
3.1.2 进行控制台配置规则与测试
从上图结果得出, 控制台的限流规则异常
blockHandler
优先级更大。
1