自定义sentinel熔断降级处理方法,blockHandler,block Handler Class,fallback,fallbackClass使用方法和注意事项

背景条件:

默认情况下sentinel发生限流或熔断是直接抛出异常BlockException然后在浏览器响应这么一句话

可见DefaultBlockExceptionHandler类源码

 但在现在的前后端分离开发中,我们一般都会统一响应格式,因此这样的返回结果往往是不能满足我们的需求的,因此我们需要自定义sentinel熔断或降级的处理方式

这是我们就需要用到@SentinelResource注解

注,默认情况下sentinel只会将controller中的接口作为资源,而Service等其他地方的方法sentinel将不会作为sentinel的资源,我们可以手动在方法上加上@SentinelResource注解将其标注为sentinel的资源

前置知识:

BlockException类,其包含五个子类,分别对应sentinel流控降级规则的授权规则、降级规则、限流规则、热点规则、系统规则 因此blockHandler()是专门用来处理sentinel异常

 @SentinelResource注解常用属性介绍

 使用方法及注意事项:

.blockHandler():

使用blockHandler()指定指定发生blockExcption时的处理方法

    @GetMapping("/hello/{id}")
    @SentinelResource(value = "hello",blockHandler = "blockHandlerMethod")
    public Result<String> hello(@PathVariable("id") String id){
        testService.test();
        return new Result<>(200,"操作成功","hello"+id);
    }

    public Result<String> blockHandlerMethod(String id, BlockException e){
        if (e instanceof DegradeException){
            return new Result<>(10000,"操作失败","服务已被降级或熔断");
        }else if(e instanceof FlowException){
            return new Result<>(10000,"操作失败","服务已被限流");

        }else { //可以继续根据blockException的类型,配置对应的返回对象
            return new Result<>();
        }
    }

效果:

限流

 降级

使用注意事项:

1.处理方法必须与受保护资源在同一个类中

2.处理方法的修饰符必须为pulbic

3.处理方法的参数列表必须和受保护资源相同,并在最后加上BlockException e接收异常

4.处理方法的返回值必须和受保护资源相同

二.blockHandlerClass

单独新建一个类用于处理受保护资源的BlockException,相比blockHandler()指定本类中的方法更加的解耦且灵活

使用方法:

处理类及处理方法

public class MyBlockExceptionHandler {
    public static Result<String> blockExceptionHandler(String id, BlockException e) {
        if (e instanceof DegradeException){
            return new Result<>(10000,"操作失败","服务已被降级或熔断---byBlockHandlerClass");
        }else if(e instanceof FlowException){
            return new Result<>(10000,"操作失败","服务已被限流---byBlockHandlerClass");

        }else { //可以继续根据blockException的类型配置对应的返回对象
            return new Result<>(1000,"操作失败","其他类型的BlockException---byBlockHandlerClass");
        }
    }
}

受保护资源上配合blockHandlerClass(指定处理方法所在的类)blockHandler(指定处理方法的名字)两个属性使用

    @GetMapping("/hello/{id}")
    @SentinelResource(value = "hello",blockHandlerClass ={MyBlockExceptionHandler.class},
                                        blockHandler = "blockExceptionHandler")
    public Result<String> hello(@PathVariable("id") String id){
        return new Result<>(200,"操作成功","hello"+id);
    }

效果

限流(流控就不展示了) 

使用注意事项:

1.指定处理方法必须是public static的

2.处理方法参数列表及返回值和 blockHandler相同

三、fallback()

注意fallback和blockHandler的区别

1. blockHandler是专门(只)处理sentinel流控降级规则抛出的BlockException

2. 而fallback默认处理所有的异常,其中包括BlockEcxeption(因为BlockException是Exception的子类),也就是说如果我们不配置blockHandler,其抛出BlockEcxeption也将会进入fallback方法中

3. fallback处理的异常可通过@SentinelResource中的exceptionsToIgnore属性排除(不知道为什么我测试可以排除ArithmeticException,但是排除不了BlockException

4. 如果同时配置了blockHandler和fallback,出现BlockException时将进入BlockHandler方法中处理

示例:为hello资源配置一个fallback方法打印异常类名,并留下一个除0异常

    @GetMapping("/hello/{num}")
    @SentinelResource(value = "hello",fallback = "fallbackMethod")
    public Result<String> hello(@PathVariable("num") Integer num){
        int result = 100/num;
        return new Result<>(200,"操作成功","hello"+result);
    }

    public Result<String> fallbackMethod (Integer num,Throwable e){
        return new Result<>(10000,"操作失败","出现"+e.getClass().getSimpleName()+"异常,进入指定的fallback方法");
    }

当我们参数输入0,抛出除0异常

当我们为hello资源进行限流,触发BlockException异常,可以看到依旧会进入我们的fallback方法

使用注意事项:

1.方法必须和被保护资源处于同一个类

2.方法参数列表和受保护资源一致(可选是否在最后添加一个Throwable类型参数接收异常,注意类型必须是Throwable)

3.方法返回值必须和受保护资源相同

四、fallbackClass

该属性类似于上面介绍的blockHandlerClass,也是为了实现灵活应用及解耦

新建fallback类及方法

public class MyFallbackHandler {
    public static Result<String> fallbackMethod (Integer num, Throwable e){
        return new Result<>(10000,"操作失败","出现"+e.getClass().getSimpleName()+"异常," +
                "                                                  进入指定的fallback方法--byMyFallBackClass");
    }
}

配合fallback()属性指定位于其他类的fallback方法

    @GetMapping("/hello/{num}")
    @SentinelResource(value = "hello",fallbackClass = {MyFallbackHandler.class},fallback = "fallbackMethod")
    public Result<String> hello(@PathVariable("num") Integer num){
        int result = 100/num;
        return new Result<>(200,"操作成功","hello"+result);
    }

效果:

除0

限流 

使用注意事项:

1.指定处理方法必须是public static的

2.处理方法参数列表及返回值等和 fallback相同

五、defaultFallback

使用方法和fallback相同,优先级低于fallback,同时配置fallback和defaultFallback时由fallback生效

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值