在之前的练习中,只要应用重启,就需要重新配置,这样在我们实际的项目是非常不实用的,那么有没有办法把我们配置的规则保存下来呢?答案是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. ShellExecute的跨平台实现OpenUrl

    OpenUrl 是 iOS 中 UIApplication 提供的一个函数,用于调用其它程序.实际上各个平台都有自己的实现,这里提供一个直接封装完的跨平台版本给大家.   uses {$IFDEF M ...

  2. C++界面库(十几种,很全)

    刚开始用C++做界面的时候,根本不知道怎么用简陋的MFC控件做出比较美观的界面,后来就开始逐渐接触到BCG  Xtreme ToolkitPro v15.0.1,Skin++,等界面库,以及一些网友自 ...

  3. vue.js执行mounted的实例

    代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" c ...

  4. 北京信息科技大学第十一届程序设计竞赛(重现赛)I

    I andy种树 题目链接:https://ac.nowcoder.com/acm/contest/940/I 题目描述 andy在他的庄园里种了n棵树,排列成一排,标号为1到n.最开始的时候n棵树的 ...

  5. 牛客假日团队赛1 B

    B.便便传送门(一) 题目链接:https://ac.nowcoder.com/acm/contest/918/B 题目 Farmer John最讨厌的农活是运输牛粪.为了精简这个过程,他制造了一个伟 ...

  6. Fiddler如何过滤无用的链接

    场景:现在是移动端的天下,测试过程中,抓包工具肯定必不可少,如何使用这里就不赘述,这里给大家讲述下如何过滤那些没有的链接,js ,png等无用的信息 工具:fiddler-use Filters功能: ...

  7. 7天入门Linux

    经过一个星期学习,Linux终于入门了,在这里小记下~ =====================分割线============================= Ubuntu常用命令: ctrl+s ...

  8. HDU 4444:Walk(思维建图+BFS)***

    http://acm.hdu.edu.cn/showproblem.php?pid=4444 题意:给出一个起点一个终点,给出n个矩形的两个对立顶点,问最少需要拐多少次弯可以从起点到达终点,如果不能输 ...

  9. svn unable to connect to a repository url 计算机积极拒绝

    网上应该说启动server服务,首先找不到这个服务,后来下载个软件有了,启动还是不行.clear了所有saved data之后也是不行. 解决方法:Network中 Enable proxy Serv ...

  10. WebSocket+Netty构建web聊天程序

    WebSocket 传统的浏览器和服务器之间的交互模式是基于请求/响应的模式,虽然可以使用js发送定时任务让浏览器在服务器中拉取但是弊端很明显,首先就是不等避免的延迟,其次就是频繁的请求,让服务器的压 ...