SpringCloud Alibaba学习(五)——@SentinelResources注解

简介

上一篇博客中,针对 @SentinelResources 注解,做了个简单的测试Demo,这一篇文章重点说明总结 @SentinelResources 的详细使用和配置。
Sentinel实现熔断、限流、降级

与HystrixCommand相比

@HystrixCommand 和 @SentinelResources 注解的功效总体而言是类似的。
springcloud 第一代不在迭代更新,阿里团队在springcloud第一代的基础上,做了一层封装,原则上还是使用大局化配置。

简单案例

之前的配置主要根据 URL的形式进行流控限流的配置和使用,本次依据 @SentinelResources 注解实现资源名称方式进行配置操作。

新建一个处理类。

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ResourcesController {

    @RequestMapping("/resources1")
    @SentinelResource(value = "resources1",blockHandler = "handler")
    public JSONObject resources1(){
        JSONObject json = new JSONObject();
        json.put("code",200);
        json.put("msg","请求成功!");
        return json;
    }

    public JSONObject handler(BlockException e){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","请求降级!");
        return json;
    }
}

启动项目,当不配置 流控规则 时,快速请求访问:

在这里插入图片描述

配置流控规则
在这里插入图片描述
请求测试:

在这里插入图片描述

异常回执配置

在Hystrix 中,出现异常后,会进入降级处理流程,但在 Sentinel 中出现异常,并不会进入降级处理操作。

异常测试

增加新的测试代码逻辑:

    // ================= 异常操作
    @RequestMapping("/resources2")
    @SentinelResource(value = "resources2",blockHandler = "handler2")
    public JSONObject resources2(){
        int a = 10/0;
        JSONObject json = new JSONObject();
        json.put("code",200);
        json.put("msg","请求成功!");
        return json;
    }

    public JSONObject handler2(BlockException e){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","请求降级!");
        return json;
    }

在这里插入图片描述

异常降级处理操作流程

采取@SentinelResources 注解中的fallback属性配置异常降级流程。

    // ================= 异常操作
    @RequestMapping("/resources2")
    @SentinelResource(value = "resources2",
	    blockHandler = "handler2",
	    fallback = "fallback2")
    public JSONObject resources2(){
        int a = 10/0;
        JSONObject json = new JSONObject();
        json.put("code",200);
        json.put("msg","请求成功!");
        return json;
    }

    public JSONObject fallback2(){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","fallback2 请求降级!");
        return json;
    }

    public JSONObject handler2(BlockException e){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","请求降级!");
        return json;
    }

在这里插入图片描述

深层次的思考

@SentinelResources 注解中,每次进行配置流控降级处理操作时,都需要指定一个或多个blockHandler;或者出现异常降级时,一个处理方法指定一个fallback
能否有一种全局化的配置,只需要进行调用即可呢?

答案是有的,可以采取专门定义一个 blockHandler 类和fallback类的方式。

定义两个类,分别为 blockHandler 类和fallback类。
在这里插入图片描述
其中,blockHandler 类的处理方法有

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSONObject;

public class HandlerGlobal {

    public static JSONObject handler1(String msg,BlockException e){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","请求降级!----1");
        return json;
    }

    public static JSONObject handler2(String msg,BlockException e){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","请求降级!----2");
        return json;
    }
}

fallback类的处理方法有:

import com.alibaba.fastjson.JSONObject;

public class Fallback {
    public static JSONObject fallback1(String msg){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","fallback1 请求降级!");
        return json;
    }

    public static JSONObject fallback2(String msg){
        JSONObject json = new JSONObject();
        json.put("code",300);
        json.put("msg","fallback2 请求降级!");
        return json;
    }
}

处理类上的引用案例:

    //============全局化调用
    @RequestMapping("/resources3")
    @SentinelResource(value = "resources3",
            blockHandlerClass = HandlerGlobal.class ,
            blockHandler = "handler2",
            fallbackClass = Fallback.class,
            fallback = "fallback1")
    public JSONObject resources3(String msg){
        if("1".equalsIgnoreCase(msg)){
            int a = 10/0;
        }
        JSONObject json = new JSONObject();
        json.put("code",200);
        json.put("msg","请求成功!");
        return json;
    }

重启项目,并配置流控规则
在这里插入图片描述
请求测试:
在这里插入图片描述
在这里插入图片描述
增加异常逻辑,请求测试:
在这里插入图片描述
[注意:] 几个需要注意的地方

1、Sentinel 的 blockHandler处理方法中,必须携带参数BlockException e,否则无法指向。
2、全局化的 blockHandler处理方法,必须为static
3、全局化的 fallback 处理方法,必须为static
4、blockHandlerfallback两个方法中的携带参数必须和请求类的保持一致!

@SentinelResources中的其他参数

@SentinelResource 注解

  • value
    资源名称,必需项(不能为空)
  • entryType
    entry 类型,可选项(默认为 EntryType.OUT
  • blockHandler / blockHandlerClass
    blockHandler 对应处理 BlockException 的函数名称,可选项。
    blockHandler 函数访问范围需要是 public返回类型需要与原方法相匹配参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException
    blockHandler 函数默认需要和原方法在同一个类中。
    若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • fallback / fallbackClass
    fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。
    fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
  • fallback 函数签名和位置要求:
  • 返回值类型必须与原函数返回值类型一致;
  • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
  • fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为static函数,否则无法解析。
  • defaultFallback
    默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。
    默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
    同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效
  • defaultFallback 函数签名要求:
  • 返回值类型必须与原函数返回值类型一致;
  • 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
  • defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为static函数,否则无法解析。
  • exceptionsToIgnore
    用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

git地址

git地址

猜你喜欢

转载自blog.csdn.net/qq_38322527/article/details/106983618