Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [規(guī)則持久化篇]

[TOC]


規(guī)則持久化 - 拉模式

在Sentinel控制臺(tái)對(duì)某個(gè)微服務(wù)的接口資源配置了流控、降級(jí)等規(guī)則后,若重啟了該微服務(wù),那么配置的相關(guān)規(guī)則就會(huì)丟失,因?yàn)镾entinel默認(rèn)將規(guī)則存放在內(nèi)存中。每次重啟微服務(wù)都得重新配置規(guī)則顯然是不合理的,所以我們需要將配置好的規(guī)則進(jìn)行持久化存儲(chǔ),而Sentinel提供了兩種規(guī)則持久化模式:

  • 拉模式(pull)
  • 推模式(push)

本小節(jié)先介紹一下拉模式(pull),該模式的架構(gòu)圖如下:


image.png
  • Tips:規(guī)則在代碼中實(shí)際上是一個(gè)對(duì)象,所以通常是轉(zhuǎn)換成json字符串后再存儲(chǔ)至本地文件

因?yàn)樾枰x寫本地文件,所以實(shí)現(xiàn)拉模式需要編寫一些代碼,首先在項(xiàng)目中添加如下依賴:

<!-- Sentinel Datasource -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-extension</artifactId>
</dependency>

由于Sentinel有好幾種規(guī)則,所以需要寫的代碼也有點(diǎn)多,具體代碼如下示例:

package com.zj.node.contentcenter.sentinel;

import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
import com.alibaba.csp.sentinel.datasource.*;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

/**
 * 規(guī)則持久化 - 拉模式
 *
 * @author 01
 * @date 2019-08-02
 **/
@Slf4j
public class FileDataSourceInitial implements InitFunc {
    /**
     * 定義并實(shí)現(xiàn)各個(gè)規(guī)則對(duì)象的轉(zhuǎn)換器,用于將json格式的數(shù)據(jù)轉(zhuǎn)換為相應(yīng)的Java對(duì)象
     */
    private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference<List<FlowRule>>() {
            }
    );

    private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference<List<DegradeRule>>() {
            }
    );

    private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference<List<SystemRule>>() {
            }
    );

    private Converter<String, List<AuthorityRule>> authorityRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference<List<AuthorityRule>>() {
            }
    );

    private Converter<String, List<ParamFlowRule>> paramFlowRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference<List<ParamFlowRule>>() {
            }
    );

    @Override
    public void init() throws Exception {
        // 規(guī)則持久化文件所存放的路徑及文件名,可以按需求自行修改
        String ruleDir = System.getProperty("user.home") + "/sentinel/rules";
        String flowRulePath = ruleDir + "/flow-rule.json";
        String degradeRulePath = ruleDir + "/degrade-rule.json";
        String systemRulePath = ruleDir + "/system-rule.json";
        String authorityRulePath = ruleDir + "/authority-rule.json";
        String paramFlowRulePath = ruleDir + "/param-flow-rule.json";

        // 目錄路徑及文件若不存在則創(chuàng)建
        this.mkdirIfNotExits(ruleDir);
        this.createFileIfNotExits(flowRulePath);
        this.createFileIfNotExits(degradeRulePath);
        this.createFileIfNotExits(systemRulePath);
        this.createFileIfNotExits(authorityRulePath);
        this.createFileIfNotExits(paramFlowRulePath);

        // 注冊各個(gè)規(guī)則的可讀寫數(shù)據(jù)源
        this.registerFlowRWDS(flowRulePath);
        this.registerDegradeRWDS(degradeRulePath);
        this.registerSystemRWDS(systemRulePath);
        this.registerAuthorityRWDS(authorityRulePath);
        this.registerParamRWDS(paramFlowRulePath);
    }

    /**
     * 注冊流控規(guī)則的可讀寫數(shù)據(jù)源
     */
    private void registerFlowRWDS(String flowRulePath) throws FileNotFoundException {
        // 構(gòu)建可讀數(shù)據(jù)源,用于定時(shí)讀取本地的json文件
        ReadableDataSource<String, List<FlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(
                flowRulePath,
                flowRuleListParser
        );
        // 將可讀數(shù)據(jù)源注冊至FlowRuleManager,當(dāng)文件里的規(guī)則內(nèi)容發(fā)生變化時(shí),就會(huì)更新到緩存里
        FlowRuleManager.register2Property(flowRuleRDS.getProperty());

        // 構(gòu)建可寫數(shù)據(jù)源
        WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(
                flowRulePath,
                this::toJson
        );
        // 將可寫數(shù)據(jù)源注冊至transport模塊的WritableDataSourceRegistry中
        // 這樣收到控制臺(tái)推送的規(guī)則時(shí),Sentinel會(huì)先更新到內(nèi)存,然后將規(guī)則寫入到文件中
        WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
    }

    /**
     * 注冊降級(jí)規(guī)則的可讀寫數(shù)據(jù)源
     */
    private void registerDegradeRWDS(String degradeRulePath) throws FileNotFoundException {
        ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(
                degradeRulePath,
                degradeRuleListParser
        );
        DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
        WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(
                degradeRulePath,
                this::toJson
        );
        WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
    }

    /**
     * 注冊系統(tǒng)規(guī)則的可讀寫數(shù)據(jù)源
     */
    private void registerSystemRWDS(String systemRulePath) throws FileNotFoundException {
        ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(
                systemRulePath,
                systemRuleListParser
        );
        SystemRuleManager.register2Property(systemRuleRDS.getProperty());
        WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(
                systemRulePath,
                this::toJson
        );
        WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
    }

    /**
     * 注冊授權(quán)規(guī)則的可讀寫數(shù)據(jù)源
     */
    private void registerAuthorityRWDS(String authorityRulePath) throws FileNotFoundException {
        ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(
                authorityRulePath,
                authorityRuleListParser
        );
        AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
        WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(
                authorityRulePath,
                this::toJson
        );
        WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
    }

    /**
     * 注冊熱點(diǎn)參數(shù)規(guī)則的可讀寫數(shù)據(jù)源
     */
    private void registerParamRWDS(String paramFlowRulePath) throws FileNotFoundException {
        ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS = new FileRefreshableDataSource<>(
                paramFlowRulePath,
                paramFlowRuleListParser
        );
        ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
        WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(
                paramFlowRulePath,
                this::toJson
        );
        ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
    }

    private void mkdirIfNotExits(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            boolean result = file.mkdirs();
            log.info("創(chuàng)建目錄: {} filePath: {}", result ? "成功" : "失敗", filePath);
        }
    }

    private void createFileIfNotExits(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            boolean result = file.createNewFile();
            log.info("創(chuàng)建文件: {} filePath: {}", result ? "成功" : "失敗", filePath);
        }
    }

    private <T> String toJson(T t) {
        return JSON.toJSONString(t);
    }
}

這里有兩個(gè)重要的API:

  • FileRefreshableDataSource 定時(shí)從指定文件中讀取規(guī)則JSON文件【上圖中的本地文件】,如果發(fā)現(xiàn)文件發(fā)生變化,就更新規(guī)則緩存
  • FileWritableDataSource 接收控制臺(tái)規(guī)則推送,并根據(jù)配置,修改規(guī)則JSON文件【上圖中的本地文件】

編寫完以上代碼后,還需要在項(xiàng)目的 resources/META-INF/services 目錄下創(chuàng)建一個(gè)文件,名為 com.alibaba.csp.sentinel.init.InitFunc ,如下圖所示:

image.png

然后編輯文件內(nèi)容如下:

# 修改為上面FileDataSourceInitial的包名類名全路徑
com.zj.node.contentcenter.sentinel.FileDataSourceInitial

完成以上步驟后,重啟項(xiàng)目,此時(shí)就可以自行測試一下規(guī)則是否能持久化存儲(chǔ)了。

拉模式的優(yōu)缺點(diǎn):

  • 優(yōu)點(diǎn):
    • 簡單易懂,沒有多余依賴(如配置中心、緩存等依賴)
  • 缺點(diǎn):
    • 由于規(guī)則是用 FileRefreshableDataSource 定時(shí)更新的,所以規(guī)則更新會(huì)有延遲。如果FileRefreshableDataSource定時(shí)時(shí)間過大,可能長時(shí)間延遲;如果FileRefreshableDataSource過小,又會(huì)影響性能
    • 規(guī)則存儲(chǔ)在本地文件,如果有一天需要遷移微服務(wù),那么需要把規(guī)則文件一起遷移,否則規(guī)則會(huì)丟失

如果有了解過規(guī)則持久化相關(guān)配置的小伙伴可能會(huì)有疑問,Spring Cloud Alibaba不是提供了如下配置了嗎?為什么要全部自己寫呢?

spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow

#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
#spring.cloud.sentinel.datasource.ds1.file.data-type=custom
#spring.cloud.sentinel.datasource.ds1.file.converter-class=com.alibaba.cloud.examples.JsonFlowRuleListConverter
#spring.cloud.sentinel.datasource.ds1.file.rule-type=flow

關(guān)于這個(gè)問題,可以查看一下這個(gè)Issues

官方文檔:


規(guī)則持久化 - 推模式

在上一小節(jié)中,我們了解了規(guī)則持久化中拉模式的原理及使用方式,本小節(jié)將介紹在生產(chǎn)環(huán)境中更為常用的推模式(push)。

推模式的架構(gòu)圖如下:


image.png
  • Sentinel控制臺(tái)不再是調(diào)用客戶端的API推送規(guī)則數(shù)據(jù),而是將規(guī)則推送到Nacos或其他遠(yuǎn)程配置中心
  • Sentinel客戶端通過連接Nacos,來獲取規(guī)則配置;并監(jiān)聽Nacos配置變化,如發(fā)生變化,就更新本地緩存(從而讓本地緩存總是和Nacos一致)
  • Sentinel控制臺(tái)也監(jiān)聽Nacos配置變化,如發(fā)生變化就更新本地緩存(從而讓Sentinel控制臺(tái)的本地緩存總是和Nacos一致)

改造Sentinel控制臺(tái)

使用推模式進(jìn)行規(guī)則的持久化還是稍微有些麻煩的,因?yàn)樾枰膭?dòng)Sentinel控制臺(tái)的源碼,對(duì)控制臺(tái)的改造主要是為了實(shí)現(xiàn):

  • DynamicRuleProvider:從Nacos上讀取配置
  • DynamicRulePublisher:將規(guī)則推送到Nacos上

這里僅演示對(duì)流控規(guī)則的改造讓其支持推模式的規(guī)則持久化,因?yàn)槠渌?guī)則的改造過程也是類似的,稍微琢磨一下就可以了。首先需要下載Sentinel的源碼包,我這里使用的是1.6.3版本:

image.png

下載并解壓完成后,使用IDE打開sentinel-dashboard這個(gè)項(xiàng)目,如下:


image.png

第一步:修改該項(xiàng)目的pom.xml文件,找到如下依賴項(xiàng):

<!-- for Nacos rule publisher sample -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <scope>test</scope>
</dependency>

<scope>test</scope>一行注釋掉,即修改為如下:

<!-- for Nacos rule publisher sample -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <!-- <scope>test</scope> -->
</dependency>

第二步:找到 sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos目錄,將整個(gè)目錄拷貝到 sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos下,如下圖所示:

image.png

拷貝完成后rule包結(jié)構(gòu)如下圖:


image.png

第三步:修改流控規(guī)則Controller,到com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2類的源碼中找到這一段:

@Autowired
@Qualifier("flowRuleDefaultProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleDefaultPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

修改@Qualifier注解的內(nèi)容,將其修改為:

@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

第四步:打開sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html文件,找到一段被注釋的代碼,如下:

  <!--<li ui-sref-active="active" ng-if="entry.appType==0">-->
    <!--<a ui-sref="dashboard.flow({app: entry.app})">-->
      <!--<i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控規(guī)則 V1</a>-->
  <!--</li>-->

只需要把注釋解開,即改為:

  <li ui-sref-active="active" ng-if="entry.appType==0">
    <a ui-sref="dashboard.flow({app: entry.app})">
      <i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控規(guī)則 V1</a>
  </li>

到這步為止,我們就對(duì)sentinel-dashboard源碼改造完畢了,現(xiàn)在流控規(guī)則就可以支持推模式的持久化了,接下來就是編譯、啟動(dòng)以及測試。

打開idea的terminal,執(zhí)行如下命令進(jìn)行打包編譯:

mvn clean package -DskipTests

然后進(jìn)入target目錄,使用如下命令執(zhí)行jar包,啟動(dòng)Sentinel控制臺(tái):

java -jar sentinel-dashboard.jar

注:也可以選擇直接在idea中點(diǎn)擊啟動(dòng)按鈕來啟動(dòng)Sentinel控制臺(tái),效果是一樣的

啟動(dòng)完成后,使用瀏覽器打開,可以看到Sentinel的菜單欄中比之前多出了一項(xiàng)流控規(guī)則 V1

image.png

注:若沒有顯示該項(xiàng),可以嘗試清除瀏覽器緩存或換個(gè)瀏覽器打開


改造Sentinel客戶端( 微服務(wù))

改造完控制臺(tái)后,接下來開始改造客戶端,首先在項(xiàng)目中添加如下依賴:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

然后添加各個(gè)規(guī)則配置:

spring:
  cloud:
    sentinel:
      datasource:
        # 名稱隨意
        flow:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-flow-rules
            groupId: SENTINEL_GROUP
            # 規(guī)則類型,取值見:
            # org.springframework.cloud.alibaba.sentinel.datasource.RuleType
            rule-type: flow
        degrade:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-degrade-rules
            groupId: SENTINEL_GROUP
            rule-type: degrade
        system:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-system-rules
            groupId: SENTINEL_GROUP
            rule-type: system
        authority:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-authority-rules
            groupId: SENTINEL_GROUP
            rule-type: authority
        param-flow:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-param-flow-rules
            groupId: SENTINEL_GROUP
            rule-type: param-flow

完成以上步驟后重啟項(xiàng)目,然后回到Sentinel控制臺(tái)里的流控規(guī)則 V1中新增流控規(guī)則,之所以不在簇點(diǎn)鏈路中添加,是因?yàn)榇攸c(diǎn)鏈路中的按鈕依舊是調(diào)用之前的邏輯添加到內(nèi)存中。新增流控規(guī)則如下:

image.png

新增完成后,到Nacos Server的配置列表上,可以看到該規(guī)則的配置數(shù)據(jù),證明已經(jīng)持久化存儲(chǔ)到Nacos了:


image.png

若直接在Nacos上修改流控規(guī)則,然后刷新Sentinel控制臺(tái),控制臺(tái)上的顯示也會(huì)被修改

此時(shí)重啟Sentinel控制臺(tái)和微服務(wù),然后刷新控制臺(tái),可以發(fā)現(xiàn)該流控規(guī)則依舊存在:


image.png

以上折騰了那么多只實(shí)現(xiàn)了流控規(guī)則的持久化,這還是因?yàn)楣俜綔?zhǔn)備好了示例代碼。Sentinel有若干種規(guī)則,例如降級(jí)規(guī)則、系統(tǒng)規(guī)則、授權(quán)規(guī)則、熱點(diǎn)規(guī)則等,都需要使用類似的方式,修改 com.alibaba.csp.sentinel.dashboard.controller 包中對(duì)應(yīng)的Controller,才能實(shí)現(xiàn)持久化,所以本小節(jié)僅是拋磚引玉,其他規(guī)則可以自行動(dòng)手參考著實(shí)現(xiàn)。

推模式優(yōu)缺點(diǎn):

  • 優(yōu)點(diǎn):
    • 一致性良好,性能優(yōu)秀,貼近生產(chǎn)使用
  • 缺點(diǎn):
    • 需要對(duì)控制臺(tái)的源碼進(jìn)行改動(dòng)比較麻煩,并且所有規(guī)則加起來的改動(dòng)工作量較大
    • 引入額外的依賴(Nacos)

官方文檔:


將應(yīng)用接入阿里云 AHAS 服務(wù)

在生產(chǎn)環(huán)境使用Sentinel是必須要實(shí)現(xiàn)規(guī)則持久化的,而通過以上兩個(gè)小節(jié)的學(xué)習(xí),我們可以得知不管使用哪個(gè)模式都需要進(jìn)行相應(yīng)的改動(dòng),其中想要實(shí)現(xiàn)貼近生產(chǎn)使用的推模式需要改動(dòng)的地方更多更麻煩。

如果不想做這些麻煩的改動(dòng),又希望在生產(chǎn)環(huán)境使用Sentinel的話,則需要考慮使用阿里云提供的在線托管Sentinel控制臺(tái)(AHAS),該在線Sentinel控制臺(tái)實(shí)現(xiàn)了推模式的規(guī)則持久化并可用于生產(chǎn):

接下來演示一下如何使用這個(gè)在線的Sentinel控制臺(tái),根據(jù)開通說明文檔注冊了阿里云賬戶后,進(jìn)入開通頁面:


image.png

根據(jù)提示開通完成后,進(jìn)入管理控制臺(tái),點(diǎn)擊接入應(yīng)用流控:


image.png

進(jìn)入應(yīng)用接入界面后可以選擇不同的應(yīng)用接入,這里按照Spring Boot應(yīng)用接入的說明完成相應(yīng)步驟:


image.png

需要說明一下的是,第二步中的HTTP接口埋點(diǎn)和普通接口埋點(diǎn)都可以省略掉,因?yàn)?code>spring-cloud-starter-alibaba-sentinel依賴包里已經(jīng)實(shí)現(xiàn)了,但需要排除該依賴中的sentinel-transport-simple-http模塊,避免連接了本地的Sentinel控制臺(tái),即修改依賴如下并添加AHAS Client依賴:

<!-- Sentinel -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <!-- 排除該模塊的目的是不與本地的Sentinel控制臺(tái)進(jìn)行通信,以免造成不必要的干擾 -->
    <exclusions>
        <exclusion>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- ahas client -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>spring-boot-starter-ahas-sentinel-client</artifactId>
    <version>1.3.3</version>
</dependency>

除了修改依賴以外,還需要將配置文件中關(guān)于Sentinel控制臺(tái)的配置都注釋掉,因?yàn)榇藭r(shí)我們連接的是在線的Sentinel控制臺(tái)。如下:


image.png

然后只需要添加AHAS的啟動(dòng)參數(shù):

ahas:
  license: xxxxxxxxx
  namespace: default
project:
  name: ${spring.application.name}

完成以上步驟后,重啟項(xiàng)目并訪問該項(xiàng)目的接口,應(yīng)用正常接入的情況下可以在阿里云的控制臺(tái)中看到該應(yīng)用的展示,如下:


image.png

點(diǎn)擊該應(yīng)用就可以進(jìn)入到Sentinel控制臺(tái),可以看到這里基本上和我們自己搭建的Sentinel控制臺(tái)是差不多的,同樣支持實(shí)時(shí)監(jiān)控、查看簇點(diǎn)鏈路及配置各種規(guī)則:


image.png

例如流控規(guī)則的添加也是一樣的,只是界面稍微好看一點(diǎn)而已:


image.png

至此就完成將應(yīng)用接入AHAS了,由于操作與Sentinel控制臺(tái)基本一樣這里就不展開介紹了,可以自行測試搗鼓一下,反正可視化的頁面使用起來還是比較容易的。


集群流控

Sentinel的集群流控功能目前還不支持在生產(chǎn)環(huán)境使用,并且通過集成網(wǎng)關(guān)組件也可以實(shí)現(xiàn)類似集群流控的效果,所以這里不做過多的介紹,若感興趣的話,可以參考官方文檔和相關(guān)教程:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,310評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,566評(píng)論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,055評(píng)論 1 322
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,303評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,799評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,683評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,899評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,135評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評(píng)論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,528評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,844評(píng)論 2 372

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