Alibaba Sentinel @SentinelResource(blockHandler和fallback)

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定义的函数方法。
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值