问题
通过@SentinelResource
设置定制的fallback、blockhandler方法。
@GetMapping(value = "/test")
@SentinelResource(value = "test", fallbackClass = ControllerFallback.class, fallback = "handlerFallback", // fallback只负责业务异常
blockHandlerClass = ControllerBlockHandler.class, blockHandler = "handlerException1", // blockHandler只负责sentinel控制台配置违规
exceptionsToIgnore = {IllegalArgumentException.class})
public Result<String> test(@RequestParam(value = "id") String id) throws InterruptedException {
log.info("有用户访问 test");
int i = 10 / 0;
// TimeUnit.SECONDS.sleep(http://img.itvip666.com/group1/M00/00/09/wKgB_F-eNtOAVp9cAABTsoCoCHE995.png);
return new Result<>().ok("测试通过啦");
}
但是我们也不可能每个限制的方法上面,都要去设置@SentinelResource;这样代码太冗余了。
全局统一处理
定义一个类实现 BlockExceptionHandler
接口
注意
- Alibaba v2.1.0和Alibaba v2.2.0不一样,接口发生了变化
- 下面的代码是针对 spring cloud Alibaba v2.2.0
/**
* 定义BlockExceptionHandler接口限流处理逻辑
*/
public class CustomBlockHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
Result<String> result = new Result<String>();
// 不通的异常可以做不同的事情
// 如果是限流异常
if (e instanceof FlowException) {
result = new Result<String>().error("限流了");
} else if (e instanceof DegradeException) {
result = new Result<String>().error("降级异常");
} else if (e instanceof ParamFlowException) {
result = new Result<String>().error("热点参数限流");
} else if (e instanceof SystemBlockException) {
result = new Result<String>().error("系统异常");
} else if (e instanceof AuthorityException) {
result = new Result<String>().error("授权异常");
}
httpServletResponse.setStatus(500);
httpServletResponse.setCharacterEncoding("utf-8");
httpServletResponse.setHeader("Content-Type","application/json;charset=UTF-8");
httpServletResponse.setContentType("application/json;charset=utf-8");
new ObjectMapper()
.writeValue(httpServletResponse.getWriter(),result);
}
}
- CustomBlockHandlerConfig,将自定义的降级处理类加入到spring容器中
@Configuration
public class CustomBlockHandlerConfig {
@Bean
public BlockExceptionHandler getBlockExceptionHandler() {
return new CustomBlockHandler();
}
}
测试
我设置的是流控,当快速点击的时候就会发生限流异常