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地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章