Spring Cloud Alibaba Sentinel組件

什么是服務(wù)雪崩效應(yīng)

服務(wù)雪崩效應(yīng)是一種因“服務(wù)提供者服務(wù)的不可用”(原因)導(dǎo)致“服務(wù)調(diào)用者服務(wù)不可用”(結(jié)果)潦牛,并將不可用逐漸放大的現(xiàn)象伞梯。如下圖所示


image.png

形成原因

服務(wù)雪崩的過程可以分為三個(gè)階段:

  • 服務(wù)提供者不可用骗绕;
  • 重試加大請(qǐng)求流量隅熙;
  • 服務(wù)調(diào)用者不可用遍愿;
    服務(wù)雪崩的每個(gè)階段都可能由不同的原因造成奔滑,總結(jié)如下:


    image.png

應(yīng)對(duì)策略

常見容錯(cuò)方案:

1耙考、超時(shí)
2谜喊、限流
3、艙壁模式(如每個(gè)controller都有自己獨(dú)立的線程池倦始,之間互不干擾)
4斗遏、斷路器模式

image.png

全面應(yīng)對(duì)策略:

image.png

Sentinel 是什么

隨著微服務(wù)的流行,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來越重要鞋邑。Sentinel阿里中間件團(tuán)隊(duì)開源的诵次,面向分布式服務(wù)架構(gòu)的輕量級(jí)高可用流量控制組件,主要以流量為切入點(diǎn)枚碗,從流量控制逾一、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度來幫助您保護(hù)服務(wù)的穩(wěn)定性肮雨。

大家可能會(huì)問:Sentinel 和之前常用的熔斷降級(jí)庫 Netflix Hystrix 有什么異同呢遵堵?Sentinel官網(wǎng)有一個(gè)對(duì)比的文章,這里摘抄一個(gè)總結(jié)的表格怨规,具體的對(duì)比可以點(diǎn)此 鏈接 查看陌宿。

對(duì)比內(nèi)容 Sentinel Hystrix
隔離策略 信號(hào)量隔離 線程池隔離/信號(hào)量隔離
熔斷降級(jí)策略 基于響應(yīng)時(shí)間或失敗比率 基于失敗比率
實(shí)時(shí)指標(biāo)實(shí)現(xiàn) 滑動(dòng)窗口 滑動(dòng)窗口(基于 RxJava)
規(guī)則配置 支持多種數(shù)據(jù)源 支持多種數(shù)據(jù)源
擴(kuò)展性 多個(gè)擴(kuò)展點(diǎn) 插件的形式
基于注解的支持 支持 支持
限流 基于 QPS,支持基于調(diào)用關(guān)系的限流 不支持
流量整形 支持慢啟動(dòng)椅亚、勻速器模式 不支持
系統(tǒng)負(fù)載保護(hù) 支持 不支持
控制臺(tái) 開箱即用限番,可配置規(guī)則、查看秒級(jí)監(jiān)控呀舔、機(jī)器發(fā)現(xiàn)等 不完善
常見框架的適配 Servlet、Spring Cloud、Dubbo媚赖、gRPC 等 Servlet霜瘪、Spring Cloud Netflix

從對(duì)比的表格可以看到,Sentinel比Hystrix在功能性上還要強(qiáng)大一些惧磺,本文讓我們一起來了解下Sentinel的源碼颖对,揭開Sentinel的神秘面紗。

Sentinel功能特點(diǎn)

1磨隘、豐富的應(yīng)用場景:例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)缤底、消息削峰填谷、集群流量控制番捂、實(shí)時(shí)熔斷下游不可用應(yīng)用等
2个唧、完備的實(shí)時(shí)監(jiān)控:Sentinel 同時(shí)提供實(shí)時(shí)的監(jiān)控功能。您可以在控制臺(tái)中看到接入應(yīng)用的單臺(tái)機(jī)器秒級(jí)數(shù)據(jù)设预,甚至 500 臺(tái)以下規(guī)模的集群的匯總運(yùn)行情況徙歼。
3、廣泛的開源生態(tài):Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊鳖枕,例如與 Spring Cloud魄梯、Dubbo、gRPC 的整合宾符。您只需要引入相應(yīng)的依賴并進(jìn)行簡單的配置即可快速地接入 Sentinel酿秸。
4、完善的 SPI 擴(kuò)展點(diǎn):Sentinel 提供簡單易用魏烫、完善的 SPI 擴(kuò)展接口辣苏。您可以通過實(shí)現(xiàn)擴(kuò)展接口來快速地定制邏輯。例如定制規(guī)則管理则奥、適配動(dòng)態(tài)數(shù)據(jù)源等考润。

image.png

開源生態(tài)

image.png

Sentinel 分為兩個(gè)部分:

核心庫(Java 客戶端)不依賴任何框架/庫,能夠運(yùn)行于所有 Java 運(yùn)行時(shí)環(huán)境读处,同時(shí)對(duì) Dubbo / Spring Cloud 等框架也有較好的支持糊治。
控制臺(tái)(Dashboard)基于 Spring Boot 開發(fā),打包后可以直接運(yùn)行罚舱,不需要額外的 Tomcat 等應(yīng)用容器井辜。

為應(yīng)用整合Sentinel

引入maven依賴

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.8.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <!--sentinel整合之后會(huì)暴露出/actuator/sentinel-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <!--整合Spring Cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--整合Spring Cloud Alibaba-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>0.9.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

加入配置暴露/actuator/sentinel端點(diǎn)

#添加sentinel依賴后 暴露/actuator/sentinel端點(diǎn)
management:
  endpoints:
    web:
      exposure:
        include: '*'

啟動(dòng)服務(wù)訪問http://localhost:port/actuator/sentinel會(huì)返回json信息,說明已經(jīng)整合好了Sentinel

搭建Sentinel控制臺(tái)

下載Sentinel控制臺(tái):https://github.com/alibaba/Sentinel/releases

為服務(wù)整合Sentinel控制臺(tái):

spring:
    cloud:
        sentinel:
        filter:
            #打開/關(guān)閉掉對(duì)Spring MVC端點(diǎn)的保護(hù)
            enabled: true
        transport:
            port: 8719
            #指定sentinel控制臺(tái)的地址
            dashboard: localhost:8080
image.png

定義資源:也就是對(duì)哪個(gè)資源進(jìn)行流量控制管闷,現(xiàn)在已經(jīng)提供了注解形式粥脚,所以新的接入直接用注解,@SentinelResource

  • 關(guān)于SentinelResource注解包个,這里列出幾個(gè)好用和必填的參數(shù)刷允,具體參考這里

Sentinel控制臺(tái)配置流控規(guī)則

流控模式

  • 直接:當(dāng)QPS超過閾值就進(jìn)行限流。
  • 關(guān)聯(lián):當(dāng)關(guān)聯(lián)的資源達(dá)到閾值,就限流自己树灶。
    • 適用場景:查詢和修改同一表的數(shù)據(jù)纤怒,如果是高并發(fā)的應(yīng)用,查詢接口的流量過大天通,就會(huì)影響修改接口的性能泊窘,反之同理,這就可以根據(jù)業(yè)務(wù)需求像寒,去衡量希望優(yōu)先讀還是優(yōu)先寫烘豹。
    • 關(guān)聯(lián)其實(shí)是一種保護(hù)關(guān)聯(lián)資源的設(shè)計(jì)。
  • 鏈路:只記錄指定鏈路上的流量诺祸,即指定資源從入口資源進(jìn)來的流量如果達(dá)到閾值就限流携悯。
    • 鏈路其實(shí)是一種細(xì)粒度的針對(duì)來源,而編輯流控規(guī)則中的針對(duì)來源輸入框是微服務(wù)級(jí)別的序臂,可以指定指定微服務(wù)過來的流量達(dá)到閾值就限流蚌卤。
    • 而鏈路是api級(jí)別的,指定的是api的調(diào)用流量達(dá)到閾值就限流奥秆。
流控模式-關(guān)聯(lián)
流控模式-鏈路

流控效果

  • 快速失斞放怼:直接失敗,拋異常
    相關(guān)源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
  • Warm Up(預(yù)熱):根據(jù)codeFactor(冷加載因子构订,默認(rèn)值為3)侮叮,從閾值/codeFactor,經(jīng)過預(yù)熱時(shí)長悼瘾,才達(dá)到設(shè)置的QPS閾值囊榜。
    即如果閾值為100,冷加載因子為3亥宿,預(yù)熱時(shí)長為10秒卸勺,那么就會(huì)用100 / 3作為最初的閾值,經(jīng)過10秒之后才會(huì)將閾值達(dá)到100烫扼,進(jìn)而進(jìn)行限流曙求,意思就是讓允許通過的流量緩慢增加,在達(dá)到一定的時(shí)間之后才達(dá)到閾值這樣會(huì)更好的保護(hù)微服務(wù)
  • 排隊(duì)等待:勻速排隊(duì)映企,讓請(qǐng)求以均勻的速度通過悟狱,閾值類型必須設(shè)置成QPS,否則無效堰氓。此種模式可適用于應(yīng)對(duì)突發(fā)流量的場景
    相關(guān)源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
image.png
流控效果-排隊(duì)等待

Sentinel控制臺(tái)配置降級(jí)規(guī)則挤渐,即斷路器模式,Sentinel目前只有斷路器三態(tài)中的打開和關(guān)閉双絮,沒有半開狀態(tài)

降級(jí)策略

  • RT:平均響應(yīng)時(shí)間
    注意:Sentinel默認(rèn)RT最大時(shí)間為4900毫秒浴麻,可通過-Dcsp.sentinel.statistic.max.rt=xxx修改


    image.png
  • 異常比例


    image.png
  • 異常數(shù)
    注意:時(shí)間窗口<60秒可能會(huì)出問題
    相關(guān)源碼:com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule


    image.png

    image.png

Sentinel控制臺(tái)配置熱點(diǎn)規(guī)則得问,是一種特殊的流控規(guī)則,支持對(duì)特定的參數(shù)和參數(shù)的值限流

適用于存在熱點(diǎn)參數(shù)(某些參數(shù)QPS很高)白胀,并希望提升API可用性的場景
注意:參數(shù)必須是基本類型或者String
相關(guān)源碼:com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowChecker#passCheck()
加入代碼

@GetMapping("/test-hot")
@SentinelResource("hot")
public String testHot(@RequestParam(required = false) String a,
                      @RequestParam(required = false)String b){
    return a + ":" + b;
}
image.png

Sentinel控制臺(tái)配置系統(tǒng)規(guī)則

閾值類型

  • LOAD
    當(dāng)系統(tǒng)Load1(1分鐘的load)超過閾值椭赋,且并發(fā)線程數(shù)超過系統(tǒng)容量時(shí)觸發(fā)抚岗,建議配置為CPU核心數(shù)*2.5或杠。(僅對(duì)Linux/Unix-like 機(jī)器生效)
    系統(tǒng)容量 = maxQps * minRt
    maxQps:秒級(jí)統(tǒng)計(jì)出來的最大QPS
    minRt:秒級(jí)統(tǒng)計(jì)出來的最小響應(yīng)時(shí)間
    相關(guān)源碼:com.alibaba.csp.sentinel.slots.system.SystemRuleManager#checkBbr()
  • RT:所有入口流量的平均RT達(dá)到閾值觸發(fā)
  • 線程數(shù):所有入口流量的并發(fā)線程數(shù)達(dá)到閾值觸發(fā)
  • 入口QPS:所有入口流量的QPS達(dá)到閾值觸發(fā)
    相關(guān)源碼:com.alibaba.csp.sentinel.slots.system.SystemRuleManager#checkSystem()


    image.png

Sentinel控制臺(tái)配置授權(quán)規(guī)則

  • 白名單:資源名里的資源只允許為白名單里面的流控應(yīng)用訪問。
  • 黑名單:資源名里的資源不允許為黑名單里面的流控應(yīng)用訪問宣蔚。
  • 授權(quán)規(guī)則通過調(diào)用來源從而實(shí)現(xiàn)對(duì)服務(wù)消費(fèi)者的授權(quán)或者限制向抢。
image.png

Sentinel使用Java代碼方式配置規(guī)則

請(qǐng)點(diǎn)擊:
Alibaba Sentinel 規(guī)則參數(shù)總結(jié)
Alibaba Sentinel 配置項(xiàng)總結(jié)

Sentinel與控制臺(tái)通信原理剖析

image.png

微服務(wù)注冊到Sentinel控制臺(tái)和發(fā)送心跳源碼:com.alibaba.csp.sentinel.transport.heartbeat.SimpleHttpHeartbeatSender
微服務(wù)和Sentinel控制臺(tái)通信API源碼:com.alibaba.csp.sentinel.command.CommandHandler接口的實(shí)現(xiàn)類

修改控制臺(tái)規(guī)則是如何通知客戶端的?
看sentinel-transport-simple-http包中的HttpEventTask類胚委,它開啟了一個(gè)線程挟鸠,專門用來做為socket連接,控制臺(tái)通過socket請(qǐng)求通知客戶端亩冬,從而更新客戶端規(guī)則艘希,更改規(guī)則核心代碼如下:

long start = System.currentTimeMillis();
in = new BufferedReader(new InputStreamReader(this.socket.getInputStream(), SentinelConfig.charset()));
OutputStream outputStream = this.socket.getOutputStream();
printWriter = new PrintWriter(new OutputStreamWriter(outputStream, Charset.forName(SentinelConfig.charset())));
String line = in.readLine();
CommandCenterLog.info("[SimpleHttpCommandCenter] socket income: " + line + "," + this.socket.getInetAddress(), new Object[0]);
CommandRequest request = this.parseRequest(line);
String commandName = HttpCommandUtils.getTarget(request);
if (!StringUtil.isBlank(commandName)) {
    CommandHandler<?> commandHandler = SimpleHttpCommandCenter.getHandler(commandName);
    if (commandHandler != null) {
        CommandResponse<?> response = commandHandler.handle(request);
        this.handleResponse(response, printWriter, outputStream);
    } else {
        this.badRequest(printWriter, "Unknown command `" + commandName + '`');
    }

    printWriter.flush();
    long cost = System.currentTimeMillis() - start;
    CommandCenterLog.info("[SimpleHttpCommandCenter] Deal a socket task: " + line + ", address: " + this.socket.getInetAddress() + ", time cost: " + cost + " ms", new Object[0]);
    return;
}

this.badRequest(printWriter, "Invalid command");

Sentinel配置項(xiàng)

微服務(wù)應(yīng)用端連接Sentinel控制臺(tái)配置項(xiàng)

spring.cloud.sentinel.transport:
    # 指定控制臺(tái)的地址
    dashboard:localhost:8080
    # 指定和控制臺(tái)通信的IP
    # 如不配置,會(huì)自動(dòng)選擇一個(gè)IP注冊
    client-ip:127.0.0.1
    # 指定和控制臺(tái)通信的端口硅急,默認(rèn)8719
    # 如不設(shè)置覆享,會(huì)自動(dòng)從8719開始掃描,依次+1营袜,直到找到未被占用的端口
    port:8719
    # 心跳發(fā)送周期撒顿,默認(rèn)值null
    # 但在SimpleHttpHeartbeatSender會(huì)用默認(rèn)值10秒
    heartbeat-interval-ms:1000

Sentinel控制臺(tái)配置項(xiàng)

配置項(xiàng) 默認(rèn)值 最小值 描述
sentinel.dashboard.app.hideAppNoMachineMillis 0 60000 是否隱藏?zé)o健康節(jié)點(diǎn)的應(yīng)用,距離最近
一次主機(jī)心跳時(shí)間的毫秒數(shù)荚板,默認(rèn)關(guān)閉
sentinel.dashboard.removeAppNoMachineMillis 0 120000 是否自動(dòng)刪除無健康節(jié)點(diǎn)的應(yīng)用凤壁,距離
最近一次其下節(jié)點(diǎn)心跳時(shí)間毫秒數(shù),默
認(rèn)關(guān)閉
sentinel.dashboard.unhealthyMachineMillis 60000 30000 主機(jī)失聯(lián)判定跪另,不可關(guān)閉
sentinel.dashboard.autoRemoveMachineMillis 0 300000 距離最近心跳時(shí)間超過指定時(shí)間是否
自動(dòng)刪除失聯(lián)節(jié)點(diǎn)拧抖,默認(rèn)關(guān)閉
server.port 8080 - 指定端口
csp.sentinel.dashboard.server localhost:8080 - 指定地址
project.name - - 指定程序名稱
sentinel.dashboard.auth.username[1.6] sentinel - dashboard登錄賬號(hào)
sentinel.dashboard.auth.password[1.6] sentinel - dashboard登錄密碼
server.servlet.session.timeout[1.6] 30分鐘 - 登錄session過期時(shí)間 配置為
7200表示7200秒 配置為60m表示為60分鐘

Sentinel API

  • Sphu:定義資源,讓資源受到監(jiān)控并保護(hù)資源免绿。
  • Tracer:可以對(duì)我們想要的異常進(jìn)行統(tǒng)計(jì)唧席。
  • ContextUtil:可以實(shí)現(xiàn)調(diào)用來源,還可以標(biāo)記調(diào)用针姿。
@GetMapping("/test-sentinel-api")
public String testSentinelAPI(@RequestParam(required = false) String a){
    String resourceName = "test-sentinel-api";
    ContextUtil.enter(resourceName,"test-wfw");

    Entry entry = null;
    try {
        //定義一個(gè)sentinel保護(hù)的資源 名稱是test-sentinel-api
        entry = SphU.entry(resourceName);
        //被保護(hù)的業(yè)務(wù)邏輯
        if(StringUtils.isEmpty(a)){
            throw new IllegalArgumentException("a不能為空");
        }
        return a;
    } catch (BlockException e) {
        //如果被保護(hù)的資源被限流或者降級(jí)了袱吆,就會(huì)拋BlockException
        log.warn("限流,或者降級(jí)了...",e);
        return "限流距淫,或者降級(jí)了...";
    }catch (IllegalArgumentException e) {
        //統(tǒng)計(jì)IllegalArgumentException發(fā)生的次數(shù)绞绒,發(fā)生的占比等
        Tracer.trace(e);
        return "參數(shù)非法...";
    } finally {
        if(entry != null){
            //退出entry
            entry.exit();
        }
        ContextUtil.exit();
    }
}
流控規(guī)則-針對(duì)來源

Sentinel @SentinelResource詳解

@SentinelResource使用方式一

//使用blockHandler屬性,blockHandler的方法必須和資源在同一類中榕暇,并且有相同的參數(shù)和返回值
@PostMapping
@SentinelResource(value = "createOrder",blockHandler = "doOnBlock")
public OrderInfo create(@RequestBody OrderInfo order, @AuthenticationPrincipal String username){
    log.info("用戶名為:username={}",username);
    PriceInfo priceInfo = priceFeignClient.getPrice(order.getProductId());
    log.info("商品價(jià)格為,priceInfo={}",priceInfo);
    return order;
}

public OrderInfo doOnBlock(@RequestBody OrderInfo order, @AuthenticationPrincipal String username, BlockException exception){
    log.info("blocked by :blockException={}",exception.getClass().getSimpleName());
    return order;
}

@SentinelResource使用方式二

@PostMapping
@SentinelResource(value = "createOrder",blockHandler = "doOnBlock",blockHandlerClass = SentinelBlockHandler.class)
public OrderInfo create(@RequestBody OrderInfo order, @AuthenticationPrincipal String username){
    log.info("用戶名為:username={}",username);
    PriceInfo priceInfo = priceFeignClient.getPrice(order.getProductId());
    log.info("商品價(jià)格為,priceInfo={}",priceInfo);
    return order;
}

@Slf4j
public class SentinelBlockHandler {

    public static OrderInfo doOnBlock(@RequestBody OrderInfo order, @AuthenticationPrincipal String username, BlockException exception){
        log.info("blocked by :blockException={}",exception.getClass().getSimpleName());

        return order;
    }
}

@SentinelResource其與屬性和新增屬性

屬性 作用 是否必須
value 資源名稱
entryType entry類型蓬衡,標(biāo)記流量的方向喻杈,取值IN/OUT,默認(rèn)是OUT
blockHandler 處理BlockException的函數(shù)名稱狰晚。函數(shù)要求:
1. 必須是 public
2.返回類型與原方法一致
3. 參數(shù)類型需要和原方法相匹配筒饰,并在最后加 BlockException 類型
的參數(shù)。
4. 默認(rèn)需和原方法在同一個(gè)類中壁晒。若希望使用其他類的函數(shù)瓷们,可配置
blockHandlerClass ,并指定blockHandlerClass里面的方法秒咐。
blockHandlerClass 存放blockHandler的類谬晕。對(duì)應(yīng)的處理函數(shù)必須static修飾,
否則無法解析携取,其他要求:同blockHandler攒钳。
fallback 用于在拋出異常的時(shí)候提供fallback處理邏輯。fallback函數(shù)可以針對(duì)
所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)
進(jìn)行處理雷滋。函數(shù)要求:
1. 返回類型與原方法一致
2. 參數(shù)類型需要和原方法相匹配不撑,Sentinel 1.6開始,
也可在方法最后加 Throwable 類型的參數(shù)晤斩。
3.默認(rèn)需和原方法在同一個(gè)類中焕檬。若希望使用其他類的函數(shù),
可配置 fallbackClass 尸昧,并指定fallbackClass里面的方法揩页。
fallbackClass【1.6】 存放fallback的類。對(duì)應(yīng)的處理函數(shù)必須static修飾烹俗,
否則無法解析爆侣,其他要求:同fallback。
defaultFallback【1.6】 用于通用的 fallback 邏輯幢妄。默認(rèn)fallback函數(shù)可以針對(duì)所有類型的
異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進(jìn)行處理兔仰。
若同時(shí)配置了 fallback 和defaultFallback,以fallback為準(zhǔn)蕉鸳。
函數(shù)要求:1. 返回類型與原方法一致
2. 方法參數(shù)列表為空乎赴,或者有一個(gè) Throwable 類型的參數(shù)。
3. 默認(rèn)需要和原方法在同一個(gè)類中潮尝。若希望使用其他類的函數(shù)榕吼,
可配置 fallbackClass ,并指定 fallbackClass 里面的方法勉失。
exceptionsToIgnore【1.6】 指定排除掉哪些異常羹蚣。排除的異常不會(huì)計(jì)入異常統(tǒng)計(jì),
也不會(huì)進(jìn)入fallback邏輯乱凿,而是原樣拋出顽素。
exceptionsToTrace 需要trace的異常 Throwable

@SentinelResource相關(guān)源碼

com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect
com.alibaba.csp.sentinel.annotation.aspectj.AbstractSentinelAspectSupport

RestTemplate整合Sentinel

@Bean
@LoadBalanced
@SentinelRestTemplate
public RestTemplate RestTemplate(){

    return new RestTemplate(new HttpComponentsClientHttpRequestFactory());
}

resttemplate:
  sentinel:
    #false 關(guān)閉@SentinelRestTemplate注解咽弦,在做開發(fā)調(diào)試的時(shí)候可以關(guān)閉此注解,專注于功能的實(shí)現(xiàn)
    enabled: true

相關(guān)源碼:org.springframework.cloud.alibaba.sentinel.custom.SentinelBeanPostProcessor

Feign整合Sentinel

feign:
  sentinel:
    #為feign整合Sentinel
    enabled: true

發(fā)生限流降級(jí)時(shí)胁出,自定義處理邏輯

使用@FeignClient的fallback屬性

@FeignClient(value="priceServer",fallback = PriceFeignClientFallback.class)
public interface PriceFeignClient {

    @GetMapping(value = "/prices/{id}")
    PriceInfo getPrice(@PathVariable("id") Integer id);
}

/**
 * 發(fā)生限流降級(jí)時(shí)型型,自定義處理邏輯
 *
 * 一旦PriceFeignClient中遠(yuǎn)程調(diào)用的getPrice()方法被流控了或發(fā)生異常了,就會(huì)進(jìn)入此方法
 * 這就相當(dāng)于一個(gè)兜底的行為全蝶,保證了服務(wù)的可用
 */

@Component
public class PriceFeignClientFallback implements PriceFeignClient {

    @Override
    public PriceInfo getPrice(Integer id) {
        PriceInfo priceInfo = new PriceInfo();
        priceInfo.setId(id);
        priceInfo.setPrice(new BigDecimal(id));
        return priceInfo;
    }
}

使用@FeignClient的fallbackFactory屬性闹蒜,推薦使用這種方案

@FeignClient(value="priceServer",fallbackFactory = PriceFeignClientFallbackFactory.class)
public interface PriceFeignClient {

    @GetMapping(value = "/prices/{id}")
    PriceInfo getPrice(@PathVariable("id") Integer id);
}

/**
 * 發(fā)生限流降級(jí)時(shí),自定義處理邏輯
 * 一旦PriceFeignClient中遠(yuǎn)程調(diào)用的getPrice()方法被流控了或發(fā)生異常了裸诽,就會(huì)進(jìn)入此方法
 * 這就相當(dāng)于一個(gè)兜底的行為嫂用,保證了服務(wù)的可用
 * 相比于FeignClient中的fallback屬性而言,fallbackFactory屬性在fallback的基礎(chǔ)上可以拿到異常信息
 */

@Component
@Slf4j
public class PriceFeignClientFallbackFactory implements FallbackFactory<PriceFeignClient> {

    @Override
    public PriceFeignClient create(Throwable throwable) {
        return new PriceFeignClient() {
            @Override
            public PriceInfo getPrice(Integer id) {
                log.error("遠(yuǎn)程調(diào)用被限流或降級(jí)了丈冬,throwable={}",throwable);
                PriceInfo priceInfo = new PriceInfo();
                priceInfo.setId(id);
                priceInfo.setPrice(new BigDecimal(id));
                return priceInfo;
            }
        };
    }
}

相關(guān)源碼:org.springframework.cloud.alibaba.sentinel.feign.SentinelFeign

Sentinel使用方式總結(jié)

使用方式 使用方式 使用方法
編碼方式 API try...catch...finally
注解方式 @SentinelResource blockHandler / fallback
RestTemplate @SentinelRestTemplate blockHandler / fallback
Feign feign.sentinel.enabled=true fallback / fallbackFactory

Sentinel規(guī)則持久化方案推薦:

Alibaba Sentinel規(guī)則持久化-推模式-手把手教程【基于Nacos】

https://github.com/eacdy/Sentinel-Dashboard-Nacos/releases

https://github.com/alibaba/Sentinel/wiki/在生產(chǎn)環(huán)境中使用-Sentinel#pull模式

參考:

http://www.reibang.com/p/0e218ef7f505

https://blog.csdn.net/sheinenggaosuwo/article/details/86592893

https://blog.csdn.net/xudawenfighting/article/details/80127279

阿里熔斷限流Sentinel研究

阿里sentinel源碼研究深入

http://www.reibang.com/p/ed57014e1abb

Sentinel-開源版本Dashboard集成Apollo配置中心

阿里Sentinel控制臺(tái)源碼修改-對(duì)接Apollo規(guī)則持久化

Alibaba Sentinel 配置項(xiàng)總結(jié)

SentinelResource注解 屬性總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市甘畅,隨后出現(xiàn)的幾起案子埂蕊,更是在濱河造成了極大的恐慌,老刑警劉巖疏唾,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓄氧,死亡現(xiàn)場離奇詭異,居然都是意外死亡槐脏,警方通過查閱死者的電腦和手機(jī)喉童,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顿天,“玉大人堂氯,你說我怎么就攤上這事∨品希” “怎么了咽白?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸟缕。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么司草? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任没陡,我火速辦了婚禮,結(jié)果婚禮上番甩,老公的妹妹穿的比我還像新娘侵贵。我一直安慰自己,他們只是感情好对室,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布模燥。 她就那樣靜靜地躺著咖祭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔫骂。 梳的紋絲不亂的頭發(fā)上么翰,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音辽旋,去河邊找鬼浩嫌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛补胚,可吹牛的內(nèi)容都是我干的码耐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼溶其,長吁一口氣:“原來是場噩夢啊……” “哼骚腥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瓶逃,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤束铭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后厢绝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體契沫,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年昔汉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了懈万。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡靶病,死狀恐怖会通,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嫡秕,我是刑警寧澤渴语,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站昆咽,受9級(jí)特大地震影響驾凶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掷酗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一调违、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泻轰,春花似錦技肩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旋奢。三九已至,卻和暖如春然痊,著一層夾襖步出監(jiān)牢的瞬間至朗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工剧浸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锹引,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓唆香,卻偏偏與公主長得像嫌变,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子躬它,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容