五. SpringCloud Alibaba Sentinel 自定义降级

2023-11-03

一. 简单解释

  1. 在前面配置限流,熔断降级时,可以针对url 设置限流,或使用@SentinelResource 注解针对资源名称设置接口限流熔断降级等
  2. 出现的情况:
  • 针对 Url 对接口设置限流熔断降级设置时,如果触发降级,再去请求接口,执行Sentinel默认降级方法抛出"Blocked by Sentinel (flow limiting)"信息
  • 使用 @SentinelResource 设置资源名称,针对资源名称对接口设置限流熔断降级时,可以通过 @SentinelResource 中的 blockHandler 属性设置降级方法,当触发降级时执行该属性指向的降级方法,如果不添加该属性时,会通过 Sentinel 报错(该属性添加的降级方法是针对触发降级后执行的,如果方法执行抛出了异常,不会执行降级)
  1. 针对以上两种情况分析存在的问题:
  • 降级时执行的是系统默认的降级方法,需要修改为自定义的,根据业务给出指导的降级返回
  • 使用 @SentinelResource 的 blockHandler 添加降级方法,一个方法对应一个降级方法,并且业务代码,与降级代码耦合到在一块,需要解决耦合,与代码膨胀问题

二. @SentinelResource 注解详解

  1. @SentinelResource 注解中包含的属性
  • value String类型,必填 资源名称
  • entryType EntryType.OUT/IN 标记流量的方向
  • blockHandler String 类型,指定当前使用@SentinelResource修饰的方法触发降级时执行的降级方法,方法名
  • blockHandlerClass 与 blockHandler 注解配合使用,当 blockHandler 指定的降级方法与当前触发降级的方法不再同一个类中时,通过 blockHandlerClass 指向降级方法所在的类.class,但是在该类中 blockHandler 指定的方法必须是 static 类型否则无效
  • fallback 当 @SentinelResource修饰的方法抛出异常时执行的降级方法
  • fallbackClass 与 fallback 配合使用,当@SentinelResource修饰的方法发送异常时而 fallback 指定的降级方法与当前方法不再同一个类中,使用 fallbackClass 设置降级方法所在的类.class,注意点在该类中 fallback 指向的降级方法必须为 static 类型,否则无效
  • defaultfallBack 通用的异常降级方法
  • exceptionsToIgnore 在使用 fallback 指定当方法发生异常时执行的降级方法,但是某些情况下,方法发出异常我们并不想执行降级方法,通过该注解设置忽略哪些异常
    exceptionsToTrace 需要 trace 的异常

com.alibaba.csp.sentinel.Suhu
com.alibaba.csp.sentinel.slots.block.flow.FlowRule
com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager

三. @SentinelResource 设置异常降级方法

  1. 通过 @SentinelResource 注解的 fallback 指定当前被该注解修饰的方法抛出异常时执行的降级方法
	//当请求 /exceptionBlockTest 接口时,如果该接口发生异常,会自动执行下面的 exceptionMethod()降级方法
	@GetMapping("/exceptionBlockTest")
    @SentinelResource(value = "exceptionBlockTest", fallback = "exceptionMethod")
    public String exceptionBlockTest(String str){
        int i = 10/0;
        return "方法正常执行";
    }
    //异常降级方法,返回值类型,形参列表要与实际方法一致
    public String exceptionMethod(String str){
        System.out.println("发送异常执行的降级方法,接收参数:"+str);
        return "发送异常执行的降级方法,接收参数:"+str;
    }
  1. 通过 @SentinelResource 的 fallback 设置了当方法发生异常后执行的降级方法,在某些情况下方法发生的某些指定异常我们并不想执行降级方法,通过该注解的 exceptionsToIgnore 属性忽略指定抛出的异常
	//当请求 /exceptionBlockTest 接口时,如果该接口发生异常,会自动执行下面的 exceptionMethod()降级方法
	//但是当该方法抛出异常类型为 MyException 时,忽略不会执行降级方法
	@GetMapping("/exceptionBlockTest")
    @SentinelResource(value = "exceptionBlockTest", fallback = "exceptionMethod",exceptionsToIgnore = MyException.class)
    public String exceptionBlockTest(String str){
        throw new MyException();
        return "方法正常执行";
    }
    //异常降级方法,返回值类型,形参列表要与实际方法一致
    public String exceptionMethod(String str){
        System.out.println("发送异常执行的降级方法,接收参数:"+str);
        return "发送异常执行的降级方法,接收参数:"+str;
    }

三. @SentinelResource 降级方法与业务接口的解耦

  1. 根据降级的不同分为两种,针对流量控制,熔断控制等触发的降级与方法抛出异常时的异常降级
  2. 专门创建一个用来存放降级方法的类,类中创建对应业务接口的降级方法,降级方法必须为 static 类型,

blockHandler 触发类型的降级方法形参中必须包含 BlockException
fallback 抛出异常的降级类型,降级方法方法形参方法返回值要与对应的实际方法一致

3. blockHandler 触发降级类型

  • 创建专门存放降级方法的类,该类中的降级方法必须为 static 类型,形参中必须包含 BlockException
import com.alibaba.csp.sentinel.slots.block.BlockException;

public class CustomerBlockHandler {

    public static String bolckMethod1(BlockException exception){
        System.out.println("降级方法执行1");
        return "降级方法执行1";
    }

    public static String bolckMethod2(BlockException exception){
        System.out.println("降级方法执行2");
        return "降级方法执行2";
    }
}
  • 需要设置降级实际请求接口,通过注解的 blockHandlerClass 属性指定降级方法所在的类,通过注解的 blockHandler 属性指定执行哪个降级方法
	//当请求该接口触发降级时,会执行 blockHandlerClass 属性指定的 CustomerBlockHandler 类中的 bolckMethod1() 方法
	@GetMapping("/blockTest")
    @SentinelResource(value = "blockTest",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "bolckMethod1")
    public String resourceTest(){
        System.out.println("方法正常执行");
        return "方法正常执行";
    }

4. fallback 异常方式的降级

  • 创建专门存放降级方法的类,该类中的降级方法必须是 static类型,并且要与实际方法的形参,返回值列表一致
public class ExceptionBlockHandler {

    public static String exceptionFallBack1(String str){
        System.out.println("发送异常执行的降级方法1,接收参数:"+str);
        return "发生异常执行的降级方法1,接收参数:"+str;
    }
    public static String exceptionFallBack2(String str){
        System.out.println("发送异常执行的降级方法2,接收参数:"+str);
        return "发生异常执行的降级方法2,接收参数:"+str;
    }
}
  • 需要设置抛出异常时执行降级的接口
	//当请求该接口时,如果该接口抛出了异常,则执行 fallbackClass 指定的类 ExceptionBlockHandler 中的 exceptionFallBack2()方法
 	@GetMapping("/testExceptionBlock")
    @SentinelResource(value = "testExceptionBlock", fallbackClass = ExceptionBlockHandler.class, fallback = "exceptionFallBack2")
    public String testExceptionBlock(String str){
        int i = 10/0;
        return "方法正常执行";
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

五. SpringCloud Alibaba Sentinel 自定义降级 的相关文章

随机推荐