您好,登录后才能下订单哦!
在之前的练习中,只要应用重启,就需要重新配置,这样在我们实际的项目是非常不实用的,那么有没有办法把我们配置的规则保存下来呢?答案是YES,那么接下来,给大家来介绍如何将Sentinel规则持久化。
Document: 传送门
原理:
扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等
pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport 的WritableDataSourceRegistry中。
过程如下:
![[Spring-Cloud-Alibaba] Sentinel 规则持久化](https://cache.yisu.com/upload/information/20200311/58/228917.jpg)
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
FileRefreshableDataSource定时更新,会有延迟)FileRefreshableDataSource定时更新)推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现
ReadableDataSource接口端监听规则中心实时获取变更,流程如下:
<img src="https://user-images.githubusercontent.com/9434884/45406233-645e8380-b698-11e8-8199-0c917403238f.png" width="500" />
实现原理
shared_center service 加工
  <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-datasource-nacos</artifactId>
  </dependency>
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/nacos到 src/main/java/com/alibaba/csp/sentinel/dashboard/rule下
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>  流控规则 V1</a>-->
<!--</li>-->
---
改为
  <li ui-sref-active="active">
    <a ui-sref="dashboard.flow({app: entry.app})">
      <i class="glyphicon glyphicon-filter"></i>  NACOS 流控规则 V1</a>
  </li>
Dashboard中要修改的代码已经好了。
重新启动 Sentinel-dashboard mvn clean package -DskipTests
测试效果
Sentinel 添加流控规则:
![[Spring-Cloud-Alibaba] Sentinel 规则持久化](https://cache.yisu.com/upload/information/20200311/58/228921.jpg)
Nacos 查看同步的配置:
![[Spring-Cloud-Alibaba] Sentinel 规则持久化](https://cache.yisu.com/upload/information/20200311/58/228927.jpg)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。