在之前的练习中,只要应用重启,就需要重新配置,这样在我们实际的项目是非常不实用的,那么有没有办法把我们配置的规则保存下来呢?答案是YES,那么接下来,给大家来介绍如何将Sentinel规则持久化。

Document: 传送门

  • File Datasource(文件存储)

    • Pull 模式
    • Push 模式
  • Nacos configuration
  • Apollo
File Datasource
Pull 模式

原理:

扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等

pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport 的 WritableDataSourceRegistry 中。

过程如下:

Pull Demo
  • Step 1: 添加配置

        <dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-extension</artifactId>
    </dependency>
  • Step 2: 编写持久化代码,实现com.alibaba.csp.sentinel.init.InitFunc

    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 java.io.File;
    import java.io.IOException;
    import java.util.List; /**
    * FileDataSourceInit for : 自定义Sentinel存储文件数据源加载类
    *
    * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
    * @since 2019/7/21
    */
    public class FileDataSourceInit implements InitFunc {
    @Override
    public void init() throws Exception {
    // TIPS: 如果你对这个路径不喜欢,可修改为你喜欢的路径
    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 hotParamFlowRulePath = ruleDir + "/param-flow-rule.json"; this.mkdirIfNotExits(ruleDir);
    this.createFileIfNotExits(flowRulePath);
    this.createFileIfNotExits(degradeRulePath);
    this.createFileIfNotExits(systemRulePath);
    this.createFileIfNotExits(authorityRulePath);
    this.createFileIfNotExits(hotParamFlowRulePath);
    // 流控规则
    ReadableDataSource<String, List<FlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(
    flowRulePath,
    flowRuleListParser
    );
    // 将可读数据源注册至FlowRuleManager
    // 这样当规则文件发生变化时,就会更新规则到内存
    FlowRuleManager.register2Property(flowRuleRDS.getProperty());
    WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(
    flowRulePath,
    this::encodeJson
    );
    // 将可写数据源注册至transport模块的WritableDataSourceRegistry中
    // 这样收到控制台推送的规则时,Sentinel会先更新到内存,然后将规则写入到文件中
    WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS); // 降级规则
    ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(
    degradeRulePath,
    degradeRuleListParser
    );
    DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
    WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(
    degradeRulePath,
    this::encodeJson
    );
    WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS); // 系统规则
    ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(
    systemRulePath,
    systemRuleListParser
    );
    SystemRuleManager.register2Property(systemRuleRDS.getProperty());
    WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(
    systemRulePath,
    this::encodeJson
    );
    WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS); // 授权规则
    ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(
    flowRulePath,
    authorityRuleListParser
    );
    AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
    WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(
    authorityRulePath,
    this::encodeJson
    );
    WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS); // 热点参数规则
    ReadableDataSource<String, List<ParamFlowRule>> hotParamFlowRuleRDS = new FileRefreshableDataSource<>(
    hotParamFlowRulePath,
    hotParamFlowRuleListParser
    );
    ParamFlowRuleManager.register2Property(hotParamFlowRuleRDS.getProperty());
    WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(
    hotParamFlowRulePath,
    this::encodeJson
    );
    ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
    } /**
    * 流控规则对象转换
    */
    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>> hotParamFlowRuleListParser = source -> JSON.parseObject(
    source,
    new TypeReference<List<ParamFlowRule>>() {
    }
    ); /**
    * 创建目录
    *
    * @param filePath
    */
    private void mkdirIfNotExits(String filePath) {
    File file = new File(filePath);
    if (!file.exists()) {
    file.mkdirs();
    }
    } /**
    * 创建文件
    *
    * @param filePath
    * @throws IOException
    */
    private void createFileIfNotExits(String filePath) throws IOException {
    File file = new File(filePath);
    if (!file.exists()) {
    file.createNewFile();
    }
    } private <T> String encodeJson(T t) {
    return JSON.toJSONString(t);
    }
    }
  • Step 3: 启用上述代码

    resource 目录下创建 resources/META-INF/services 目录并创建文件com.alibaba.csp.sentinel.init.InitFunc ,内容为:

    com.sxzhongf.sharedcenter.configuration.sentinel.datasource.FileDataSourceInit
Pull 优缺点
  • 优点

    1. 简单,无任何依赖
    2. 没有额外依赖
  • 缺点
    1. 不保证一致性(规则是使用FileRefreshableDataSource定时更新,会有延迟)
    2. 实时性不保证(规则是使用FileRefreshableDataSource定时更新)
    3. 拉取过于频繁也可能会有性能问题
    4. 由于文件存储于本地,容易丢失
  • 参考资料:
    1. ITMUCH
    2. Sentinel WIKI
Push 模式

推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource接口端监听规则中心实时获取变更,流程如下:

  • 实现原理

    1. 控制台推送规则到Nacos/远程配置中心
    2. Sentinel client 舰艇Nacos配置变化,更新本地缓存
  • shared_center service 加工

    1. 添加依赖
      <dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    1. 添加配置
    spring:
    cloud:
    sentinel:
    datasource:
    sxzhongf_flow:
    nacos:
    server-addr: localhost:8848
    dataId: ${spring.application.name}-flow-rules
    groupId: SENTINEL_GROUP
    # 规则类型,取值见:org.springframework.cloud.alibaba.sentinel.datasource.RuleType
    rule_type: flow
    sxzhongf_degrade:
    nacos:
    server-addr: localhost:8848
    dataId: ${spring.application.name}-degrade-rules
    groupId: SENTINEL_GROUP
    rule-type: degrade
  • Sentinel dashboard 加工

    Dashboard 规则改造主要通过2个接口:

    com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider & com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher

    • Download Sentinel Source Code

    • 修改原sentinel-dashboard项目下的POM文件

          <!-- for Nacos rule publisher sample -->
      <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-datasource-nacos</artifactId>
      <!--注释掉原文件中的scope,让其不仅在test的时候生效-->
      <!--<scope>test</scope>-->
      </dependency>
    • 偷懒模式:复制sentinel-dashboard项目下test下的nacos包(

      src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacossrc/main/java/com/alibaba/csp/sentinel/dashboard/rule

    • 修改controller中的默认provider & publisher

      com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2

          @Autowired
      // @Qualifier("flowRuleDefaultProvider")
      @Qualifier("flowRuleNacosProvider")
      private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
      @Autowired
      // @Qualifier("flowRuleDefaultPublisher")
      @Qualifier("flowRuleNacosPublisher")
      private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
    • 打开 /Sentinel-1.6.2/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html文件,修改代码:

      <!--<li ui-sref-active="active">-->
      <!--<a ui-sref="dashboard.flow({app: entry.app})">-->
      <!--<i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控规则 V1</a>-->
      <!--</li>--> --- 改为 <li ui-sref-active="active">
      <a ui-sref="dashboard.flow({app: entry.app})">
      <i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;NACOS 流控规则 V1</a>
      </li>

    Dashboard中要修改的代码已经好了。

  • 重新启动 Sentinel-dashboard mvn clean package -DskipTests

  • 测试效果

    Sentinel 添加流控规则:

    Nacos 查看同步的配置:


[Spring-Cloud-Alibaba] Sentinel 规则持久化的更多相关文章

  1. Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵动态限流规则

    Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵动态限流规则 前面几篇文章较为详细的介绍了Sentinel的使用姿势,还没看过的小伙伴可以访问以下链接查看: &l ...

  2. Spring Cloud Alibaba | Sentinel: 分布式系统的流量防卫兵初探

    目录 Spring Cloud Alibaba | Sentinel: 分布式系统的流量防卫兵初探 1. Sentinel 是什么? 2. Sentinel 的特征: 3. Sentinel 的开源生 ...

  3. Spring Cloud Alibaba | Sentinel: 服务限流基础篇

    目录 Spring Cloud Alibaba | Sentinel: 服务限流基础篇 1. 简介 2. 定义资源 2.1 主流框架的默认适配 2.2 抛出异常的方式定义资源 2.3 返回布尔值方式定 ...

  4. Spring Cloud Alibaba | Sentinel: 服务限流高级篇

    目录 Spring Cloud Alibaba | Sentinel: 服务限流高级篇 1. 熔断降级 1.1 降级策略 2. 热点参数限流 2.1 项目依赖 2.2 热点参数规则 3. 系统自适应限 ...

  5. Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵基础实战

    Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵基础实战 Springboot: 2.1.8.RELEASE SpringCloud: Greenwich.SR2 ...

  6. Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵进阶实战

    Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵进阶实战 在阅读本文前,建议先阅读<Spring Cloud Alibaba | Sentinel:分布式系 ...

  7. Spring Cloud Alibaba Sentinel对Feign的支持

    Spring Cloud Alibaba Sentinel 除了对 RestTemplate 做了支持,同样对于 Feign 也做了支持,如果我们要从 Hystrix 切换到 Sentinel 是非常 ...

  8. Spring Cloud Alibaba Sentinel对RestTemplate的支持

    Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造 RestTemplate bean的时候需要加上 @S ...

  9. 0.9.0.RELEASE版本的spring cloud alibaba sentinel限流、降级处理实例

    先看服务提供方的,我们在原来的sentinel实例(参见0.9.0.RELEASE版本的spring cloud alibaba sentinel实例)上加上限流.降级处理,三板斧只需在最后那一斧co ...

  10. 0.9.0.RELEASE版本的spring cloud alibaba sentinel实例

    sentinel即哨兵,相比hystrix断路器而言,它的功能更丰富.hystrix仅支持熔断,当服务消费方调用提供方发现异常后,进入熔断:sentinel不仅支持异常熔断,也支持响应超时熔断,另外还 ...

随机推荐

  1. Qt Style Sheet实践(二):组合框QComboBox的定制(24K纯开源)——非常漂亮

    组合框是一个重要且应用广泛的组件,一般由两个子组件组成:文本下拉单部分和按钮部分.在许多既需要用户选择.又需要用户手动输入的应用场景下,组合框能够很好的满足我们的需求.如我们经常使用的聊天软件QQ登录 ...

  2. 当一个控件属性不存在的时候,IDE会出错在这里(说明是TWinControl.ReadState在读属性,并执行相关动作)

    procedure TWinControl.ReadState(Reader: TReader); begin DisableAlign; try inherited ReadState(Reader ...

  3. 作为服务注册中心,Eureka比Zookeeper好在哪里

    CAP是Consistency.Availablity和Partition Tolerance的缩写.一般的分布式系统最多满足其中两条.而Partition Tolerance是分布式系统的关键,因此 ...

  4. Django高级编程之自定义Field实现多语言

    自定义数据库字段 扩展默认的models.CharField和models.TextField使之成为支持多语言的字段. 可以轻松实现复用,无需配置多余选项 from django.conf impo ...

  5. 系统学习 Java IO (十二)----数据流和对象流

    目录:系统学习 Java IO---- 目录,概览 DataInputStream/DataOutputStream 允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型. 要想使用 ...

  6. SpringMVC_Two

    SpringMVC_Two 响应数据和结果视图 创建工厂 导坐标: </load-on-startup> </servlet> <servlet-mapping> ...

  7. Python爬虫的起点

    第一章主要讲解爬虫相关的知识如:http.网页.爬虫法律等,让大家对爬虫有了一个比较完善的了解和一些题外的知识点. 今天这篇文章将是我们第二章的第一篇,我们从今天开始就正式进入实战阶段,后面将会有更多 ...

  8. python基本数据类型之数字类型和其相关运算

    数字(number) Python3 支持 int.float.bool.complex(复数). 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long. ...

  9. spark入门(二)RDD基础操作

    1 简述 spark中的RDD是一个分布式的元素集合. 在spark中,对数据的所有操作不外乎创建RDD,转化RDD以及调用RDD操作进行求值,而这些操作,spark会自动将RDD中的数据分发到集群上 ...

  10. Codeforces 758A:Holiday Of Equality(水题)

    http://codeforces.com/problemset/problem/758/A 题意:给出n个值,求这里面每个值都要变成最大的那个数,总共需要加上多少. 思路:找出最大的直接算. #in ...