Version: Next
@SentinelResource 注解
从 Hystrix 的
@HystrixCommand
注解过渡到 Sentinel@SentinelResouce
注解
@SentinelResource
注解的属性
value
:资源名称,必需项(不能为空)entryType
:entry 类型,可选项(默认为EntryType.OUT
)blockHandler
/blockHandlerClass
:
blockHandler
对应处理BlockException
的函数名称,可选项。blockHandler 函数访问范围需要是public
,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException
。blockHandler 函数默认需要和原方法在同一个类中。- 若希望使用其他类的函数,则可以指定
blockHandlerClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。fallback
:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
- 返回值类型必须与原函数返回值类型一致;
- 方法参数列表需要和原函数一致,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。- fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。defaultFallback
(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
- 返回值类型必须与原函数返回值类型一致;
- 方法参数列表需要为空,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。- defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。注:1.6.0 之前的版本 fallback 函数只针对降级异常(
DegradeException
)进行处理,不能针对业务异常进行处理。
- 特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出
BlockException
时只会进入blockHandler
处理逻辑。若未配置blockHandler
、fallback
和defaultFallback
,则被限流降级时会将BlockException
直接抛出。
Cloudalibaba-sentinel-service8401
- 添加一个 Controller 类,
RateLimitController
RateLimitController@RestControllerpublic class RateLimitController {@GetMapping("/byResource")@SentinelResource(value = "byResource", blockHandler = "handleException")public CommonResult byResource() {return new CommonResult(200, "按照资源名称限流测试", new Payment(2020L, "serial001"));}public CommonResult handleException(BlockException exception) {return new CommonResult(444, exception.getClass().getCanonicalName() + "\t 服务不可用");}}
- 定义一个
/byResource
资源,如果触发了降级,则执行兜底方法handleException
按资源名限流及后续处理
- 配置的资源名与
@SentinelResource
注解的value
属性值一致
- 正常响应
- 降级响应
{
"code": 200,
"message": "按照资源名称限流测试",
"data": {
"id": 2020,
"serial": "serial001"
}
}
按 URL 地址限流及后续处理
- 通过访问 URL 来限流,会返回 Sentinel 自带 默认的限流处理信息
- 在
RateLimitController
中添加方法
RateLimitController
@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl() {
return new CommonResult(200, "按照byUrl限流测试", new Payment(2020L, "serial002"));
}
- 正常响应
- 降级响应
{
"code": 200,
"message": "按照byUrl限流测试",
"data": {
"id": 2020,
"serial": "serial002"
}
}
上述方案面临的问题
- 系统默认的,没有体现具体业务要求
- 自定义兜底方法与业务代码耦合
- 每个业务方法对应一个兜底方法,代码膨胀
- 没有体现全局统一处理
自定义限流处理逻辑
- 解耦
创建
CustomerBlockHandler
类用于自定义限流处理逻辑
- 定义降级兜底
静态
方法myhandler.CustomerBlockerHandlerpublic class CustomerBlockHandler {public static CommonResult handlerException(BlockException exception) {return new CommonResult(444,"按照客户自定义的 Glogal 全局异常处理 ---- 1",new Payment(2020L, "serial003"));}public static CommonResult handlerException2(BlockException exception) {return new CommonResult(444,"按照客户自定义的 Glogal 全局异常处理 ---- 2",new Payment(2020L, "serial003"));}}
- 在
RateLimitController
中,针对具体的业务接口,指定自定义限流处理类
- 在
@SentinelResource
注解中,blockHandlerClass
属性设置为自定义限流处理类
,blockHandler
属性设置为自定义限流处理类中的方法名
RateLimitController//CustomerBlockHandler@GetMapping("/rateLimit/customerBlockHandler")@SentinelResource(value = "customerBlockHandler",blockHandlerClass = CustomerBlockHandler.class, // 指定自定义 Handler 类blockHandler = "handlerException2")public CommonResult customerBlockHandler() {return new CommonResult(200, "按照客户自定义限流测试", new Payment(2020L, "serial003"));}
测试
- 重启
8401
- 先访问一次
http://localhost:8401/rateLimit/customerBlockHandler
- 进入 Sentinel,添加一个按资源名限流配置
- 多次访问,即可触发服务降级,可以看到执行的是定义在
自定义限流处理类
中的兜底方法
- 正常响应
- 降级响应
{"code": 200,"message": "按照客户自定义限流测试","data": {"id": 2020,"serial": "serial003"}}