zoukankan      html  css  js  c++  java
  • Spring Cloud Alibaba学习笔记(7)

    Sentinel 控制台 需要具备下面几个特性:

    • 规则管理及推送,集中管理和推送规则。sentinel-core 提供 API 和扩展接口来接收信息。开发者需要根据自己的环境,选取一个可靠的推送规则方式;同时,规则最好在控制台中集中管理。
    • 监控,支持可靠、快速的实时监控和历史监控数据查询。sentinel-core 记录秒级的资源运行情况,并且提供 API 来拉取资源运行信息。当机器大于一台以上的时候,可以通过 Dashboard 来拉取,聚合,并且存储这些信息。这个时候,Dashboard 需要有一个存储媒介,来存储历史运行情况。
    • 鉴权,区分用户角色,来进行操作。生产环境下的权限控制是非常重要的,理论上只有管理员等高级用户才有权限去修改应用的规则。

    对于规则管理及推送,规则的推送有三种模式:
    原始模式:API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource)
    这种模式简单,无任何依赖。但是不保证一致性;规则保存在内存中,重启即消失。所以不适用与生产环境,我们需要实现规则的持久话。Sentinel给我们提供了两种持久化方法,就是规则的另外两种推送模式。
    Pull 模式:扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等。优点是简单,无任何依赖;规则持久化。缺点是不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。
    Push 模式:扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源。优点是规则持久化;一致性;快速。缺点是引入了第三方依赖。

    Pull 模式【拉模式】

    Pull模式架构图

    • FileRefreshableDataSource 定时从指定文件中读取规则JSON文件【图中的本地文件】,如果发现文件发生变化,就更新规则缓存。
    • FileWritableDataSource 接收控制台规则推送,并根据配置,修改规则JSON文件【图中的本地文件】。

    实现方式

    添加依赖

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

    持久化代码

    /**
     * PULL规则持久化
     */
    public class FileDataSourceInit implements InitFunc {
        @Override
        public void init() throws Exception {
            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";
    
            this.mkdirIfNotExits(ruleDir);
            this.createFileIfNotExits(flowRulePath);
            this.createFileIfNotExits(degradeRulePath);
            this.createFileIfNotExits(systemRulePath);
            this.createFileIfNotExits(authorityRulePath);
            this.createFileIfNotExits(paramFlowRulePath);
    
            // 注册一个可读数据源,用来定时读取本地的json文件,更新到规则缓存中
            // 流控规则
            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<>(
                authorityRulePath,
                authorityRuleListParser
            );
            AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
            WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(
                authorityRulePath,
                this::encodeJson
            );
            WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
    
            // 热点参数规则
            ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS = new FileRefreshableDataSource<>(
                paramFlowRulePath,
                paramFlowRuleListParser
            );
            ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
            WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(
                paramFlowRulePath,
                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>> paramFlowRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference<List<ParamFlowRule>>() {
            }
        );
    
        private void mkdirIfNotExits(String filePath) throws IOException {
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
        }
    
        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);
        }
    }
    

    添加配置

    在项目的 resources/META-INF/services 目录下创建文件,名为 com.alibaba.csp.sentinel.init.InitFunc ,内容为:
    上面FileDataSourceInit的包名类名全路径

    Push模式

    Push模式架构图

    • 控制台推送规则:
      • 将规则推送到Nacos或其他远程配置中心
      • Sentinel客户端链接Nacos,获取规则配置;并监听Nacos配置变化,如发生变化,就更新本地缓存(从而让本地缓存总是和Nacos一致)
    • 控制台监听Nacos配置变化,如发生变化就更新本地缓存(从而让控制台本地缓存总是和Nacos一致)

    微服务改造

    添加依赖

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

    添加配置

    spring:
      cloud:
        sentinel:
          datasource:
            # 名称随意
            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
            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
    

    控制台改造

    控制台改造主要是为规则实现,需要修改源码,从https://github.com/alibaba/Sentinel 地址下载源码,进入sentinel-dashboard目录进行修改

    DynamicRuleProvider:从Nacos上读取配置
    DynamicRulePublisher:将规则推送到Nacos上

    • 修改pom.xml文件【sentinel-dashboard模块下】
      将:
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        <scope>test</scope>
    </dependency>
    

    改为:

    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    
    • 找到sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos目录,将整个目录拷贝到 sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos

    • 修改 com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2
      将:

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

    改为:

        @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;流控规则 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;流控规则 V1</a>
              </li>
    

    自此,流控规则更改为Push持久化,其他规则等照修改

    编辑/启动

    • 回到项目主目录,执行 mvn clean package -DskipTests
    • 在项目的 target 目录找到sentinel-dashboard.jar ,执行 java -jar sentinel-dashboard.jar 启动控制台。

    生产环境使用

    推荐使用Push模式

    也可以使用阿里云提供的在线托管Sentinel控制台:AHAS

  • 相关阅读:
    Linux重定向命令
    ls命令
    Linux常用命令_(进程管理)
    Linux常用命令_(文件操作)
    Linux常用命令_(文件查看)
    Linux常用命令_(文件搜索)
    Oracle表空间管理
    如何测试数据库表空间不足场景
    find命令
    各种比例尺标准分幅图经差、纬差表
  • 原文地址:https://www.cnblogs.com/fx-blog/p/11726189.html
Copyright © 2011-2022 走看看