在之前的练习中,只要应用重启,就需要重新配置,这样在我们实际的项目是非常不实用的,那么有没有办法把我们配置的规则保存下来呢?答案是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. UAC就不能一次添加、永久信任吗?

    每次都要点击确定,感觉好麻烦. 而且阻碍了某些功能的实现.

  2. 迁移到MSYS2 与 Qt 工具链注意的几个事情(g++在链接时,符号依赖项查找遵循从左至右的顺序,但qmake会自动合并造成错误。使用脚本给Mingw32-make创造出一个局部的VC编译环境)

    Microsoft Visual Studio 2015社区版提供了强大的开发体验,且 Qt 提供了预编译版本.然而,由于客户提出兼容Windows XP ~ Windows 8.1 这样宽泛的环境要 ...

  3. 比较DirectX和OpenGL的区别(比较详细)

    OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库.OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL.IRIS GL是一个工业标准的3D图形软件接口,功能虽然 ...

  4. 【DRP】-Dao层常用功能代码:增删改查

    本系列博客内容为:做DRP系统中Dao层常用功能. 该项目采用MVC架构 C(Controller)控制器,主要职责;1.取得表单参数:2.调用业务逻辑:3.转向页面 M(Model)模型,主要职责: ...

  5. 测试链接服务器sql 语句

    sp_addlinkedsrvlogin 创建或更新本地 Microsoft® SQL Server™ 实例上的登录与链接服务器上远程登录之间的映射. 语法 sp_addlinkedsrvlogin ...

  6. JVM 参数类型

    标准参数 -help -server -client -version -showversion -cp -classpath X参数 非标准化参数(在各个JDK版本中可能会变,但是变动比较小) -X ...

  7. Spark学习之路(二)—— Spark开发环境搭建

    一.安装Spark 1.1 下载并解压 官方下载地址:http://spark.apache.org/downloads.html ,选择Spark版本和对应的Hadoop版本后再下载: 解压安装包: ...

  8. Storm 学习之路(四)—— Storm集群环境搭建

    一.集群规划 这里搭建一个3节点的Storm集群:三台主机上均部署Supervisor和LogViewer服务.同时为了保证高可用,除了在hadoop001上部署主Nimbus服务外,还在hadoop ...

  9. Adboe Flash远程代码执行_CVE-2018-4878漏洞复现

    Adboe Flash远程代码执行_CVE-2018-4878漏洞复现 一.漏洞描述 该漏洞可针对windows用户发起定向攻击.攻击者可以诱导用户打开包含恶意Flash代码文件的Microsoft ...

  10. 渐进式web应用开发---service worker (二)

    阅读目录 1. 创建第一个service worker 及环境搭建 2. 使用service worker 对请求拦截 3. 从web获取内容 4. 捕获离线请求 5. 创建html响应 6. 理解 ...