文章目录
1、前言
本文内容讲述Alibaba Sentinel中,关于@SentinelResource注解中blockHandler和fallback参数的含义。以下是相关注解和用到的示例代码
- 代码示例
@GetMapping(value = "/userpass/{id}")
@SentinelResource(
value = "getUserPassById",
blockHandler = "getUserPassByIdBlockHandler", blockHandlerClass = UserBlockHandlerServiceImpl.class,
fallback = "getUserPassByIdFallback", fallbackClass = UserFallBackServiceImpl.class
)
public String getUserPassById(@PathVariable(value = "id") Long id) {
if (id < 1) {
throw new NullPointerException("id 不能是0或者负数");
}
return "123456";
}
package com.wzl.xman.servicea.service.impl;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Component;
@Component
public class UserBlockHandlerServiceImpl {
public static String getUserPassByIdBlockHandler(Long id, BlockException e) {
return "BlockHandler(触发管控规则):ID:" + id + " 管控规则内容:" + e.getRule().toString();
}
}
package com.wzl.xman.servicea.service.impl;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Component;
@Component
public class UserFallBackServiceImpl {
public static String getUserPassByIdFallback(Long id, Throwable e) {
if (e instanceof BlockException) {
BlockException blockException = (BlockException) e;
return "Fallback(触发管控规则):ID:" + id + " 管控规则内容:" + blockException.getRule().toString();
} else {
return "Fallback(服务内部异常):ID:" + id + " 服务内部异常:" + e.getMessage();
}
}
}
- 流控规则
2、blockHandler
2.1、blockHandler的定义
- blockHandler指定一个函数名称,是个可选项,用于在出现BlockException异常(触发Sentinel管控规则)的时候提供处理逻辑。
2.2、blockHandler函数签名和位置要求
- 返回值类型必须与原函数返回值类型一致。
- 方法参数列表需要和原函数一致,必须存在BlockException类型的参数用于接收对应的异常。
- blockHandler函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass为对应的类的Class对象,注意对应的函数必需用public static修饰,否则无法生效。
2.3、只有blockHandler存在时
@GetMapping(value = "/userpass/{id}")
@SentinelResource(
value = "getUserPassById",
blockHandler = "getUserPassByIdBlockHandler", blockHandlerClass = UserBlockHandlerServiceImpl.class
)
public String getUserPassById(@PathVariable(value = "id") Long id) {
if (id < 1) {
throw new NullPointerException("id 不能是0或者负数");
}
return "123456";
}
当请求频率在1秒1次的时候(QPS<=1),可以正常得到返回值
当请求频率在1秒2次的时候(QPS>1),则触发getUserPassByIdBlockHandler方法
当请求频率在1秒1次的时候(QPS<=1),触发异常
当请求频率在1秒2次的时候(QPS>1),则触发getUserPassByIdBlockHandler方法
blockHandler总结:
- 在触发定义的管控规则后,Sentinel会自动抛出BlockException异常。(BlockException的类型一共有5种)
- blockHandler定义的函数方法,只对触发了管控规则的情况进行处理(即BlockException异常),其他异常情况不作处理。
3、fallback
3.1、fallback的定义
- fallback指定一个函数名称,是个可选项,用于在抛出异常的时候提供 fallback 处理逻辑。
- fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore 里面排除掉的异常类型)进行处理。
3.2、fallback函数签名和位置要求
- 返回值类型必须与原函数返回值类型一致。
- 方法参数列表需要和原函数一致,可以额外多一个(也可以没有)Throwable类型的参数用于接收对应的异常。
- fallback函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定fallbackClass为对应的类的Class对象,注意对应的函数必需用public static修饰,否则无法生效。
3.3、只有fallback存在时
@GetMapping(value = "/userpass/{id}")
@SentinelResource(
value = "getUserPassById",
fallback = "getUserPassByIdFallback", fallbackClass = UserFallBackServiceImpl.class
)
public String getUserPassById(@PathVariable(value = "id") Long id) {
if (id < 1) {
throw new NullPointerException("id 不能是0或者负数");
}
return "123456";
}
当请求频率在1秒1次的时候(QPS<=1),可以正常得到返回值
当请求频率在1秒2次的时候(QPS>1),触发getUserPassByIdFallback方法
当请求频率在1秒1次的时候(QPS<=1),触发getUserPassByIdFallback方法
当请求频率在1秒2次的时候(QPS>1),触发getUserPassByIdFallback方法
fallback总结:
- fallback定义的函数方法,抛出了任何异常,都会触发指定函数的执行。(除了exceptionsToIgnore 里面排除掉的异常类型)
- 在触发定义的管控规则后,Sentinel会自动抛出BlockException异常。只有fallback存在,没有定义blockHandler时,此时也会触发fallback定义的函数方法。
4、blockHandler和fallback同时存在时
@GetMapping(value = "/userpass/{id}")
@SentinelResource(
value = "getUserPassById",
blockHandler = "getUserPassByIdBlockHandler", blockHandlerClass = UserBlockHandlerServiceImpl.class,
fallback = "getUserPassByIdFallback", fallbackClass = UserFallBackServiceImpl.class
)
public String getUserPassById(@PathVariable(value = "id") Long id) {
if (id < 1) {
throw new NullPointerException("id 不能是0或者负数");
}
return "123456";
}
当请求频率在1秒1次的时候(QPS<=1),可以正常得到返回值
当请求频率在1秒2次的时候(QPS>1),触发getUserPassByIdBlockHandler方法
当请求频率在1秒1次的时候(QPS<=1),触发getUserPassByIdFallback方法
当请求频率在1秒2次的时候(QPS>1),触发getUserPassByIdBlockHandler方法
总结(blockHandler和fallback同时存在时):
- 在触发定义的管控规则后,如果blockHandler存在,都是交给blockHandler定义的函数方法处理(管控规则会优先内部逻辑执行)
- 没有触发定义的管控规则,内部抛出异常,此时会触发fallback定义的函数方法。