zoukankan      html  css  js  c++  java
  • SpringCloud入门实战(10)-Sentinel使用二

    在Sentinel控制台中配置的规则,默认是保存在内存中的,重启后就会丢失;所以需要把规则持久化。

    1、规则管理及推送

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

    1.1、原始模式

    如果不做任何修改,Dashboard 的推送规则方式是通过 API 将规则推送至客户端并直接更新到内存中:

     这种做法的好处是简单,无依赖;坏处是应用重启规则就会消失,仅用于简单测试,不能用于生产环境。

    1.2、Pull模式

    pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport 的 WritableDataSourceRegistry 中。本地文件数据源会定时轮询文件的变更,读取规则。这样我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。以本地文件数据源为例,推送过程如下图所示:

     使用 pull 模式的数据源时一般不需要对 Sentinel 控制台进行改造。这种实现方法好处是简单,不引入新的依赖,坏处是无法保证监控数据的一致性。

    1.3、Push模式

    生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。

    2、规则持久化

    2.1、Pull模式持久化

    该模式只需要在应用中进行改造,不需要改造sentinel控制台。

    2.1.1、引入依赖

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

    2.1.2、编写持久化类

    package com.inspur.scdemo.server.sentinel;
    
    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.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import java.util.List;
    
    /**
     * 文件数据源
     */
    public class FileDataSourceInitFunc implements InitFunc {
        private ObjectMapper objectMapper = new ObjectMapper();
        /**流控规则对象转换*/
        private Converter<String, List<FlowRule>> flowRuleConverter = source -> {
            try {
                return objectMapper.readValue(source, new TypeReference<List<FlowRule>>(){});
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        };
        /**降级规则对象转换*/
        private Converter<String, List<DegradeRule>> degradeRuleConverter = source -> {
            try {
                return objectMapper.readValue(source, new TypeReference<List<DegradeRule>>(){});
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        };
        /**系统规则对象转换*/
        private Converter<String, List<SystemRule>> systemRuleConverter = source -> {
            try {
                return objectMapper.readValue(source, new TypeReference<List<SystemRule>>(){});
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        };
        /**授权规则对象转换*/
        private Converter<String, List<AuthorityRule>> authorityRuleConverter = source -> {
            try {
                return objectMapper.readValue(source, new TypeReference<List<AuthorityRule>>(){});
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        };
        /**授权规则对象转换*/
        private Converter<String, List<ParamFlowRule>> paramFlowRuleConverter = source -> {
            try {
                return objectMapper.readValue(source, new TypeReference<List<ParamFlowRule>>(){});
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        };
    
        @Override
        public void init() throws Exception {
            String ruleDir = "d:/temp/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";
    
            //流控规则
            ReadableDataSource<String, List<FlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(flowRulePath, flowRuleConverter);
            FlowRuleManager.register2Property(flowRuleRDS.getProperty());
    
            WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(flowRulePath, this::encodeJson);
            WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
    
            //降级规则
            ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(degradeRulePath, degradeRuleConverter);
            DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
    
            WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(degradeRulePath, this::encodeJson);
            WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
    
            //系统规则
            ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(systemRulePath, systemRuleConverter);
            SystemRuleManager.register2Property(systemRuleRDS.getProperty());
            WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(systemRulePath, this::encodeJson);
            WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
    
            //授权规则
            ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(flowRulePath, authorityRuleConverter);
            AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
            WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(authorityRulePath, this::encodeJson);
            WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
    
            //热点参数规则
            ReadableDataSource<String, List<ParamFlowRule>> hotParamFlowRuleRDS = new FileRefreshableDataSource<>(paramFlowRulePath,paramFlowRuleConverter);
            ParamFlowRuleManager.register2Property(hotParamFlowRuleRDS.getProperty());
            WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(paramFlowRulePath,this::encodeJson);
            ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
        }
    
        private <T> String encodeJson(T t) {
            try {
                return objectMapper.writeValueAsString(t);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    2.1.3、启用持久化类

    资源目录(通常是resource目录)创建META-INF/services目录,并在该目录下创建com.alibaba.csp.sentinel.init.InitFunc文件,内容为:

    com.inspur.scdemo.server.sentinel.FileDataSourceInitFunc

     2.1.3、验证

     启动sentinel控制台并启动应用,配置规则后,可以看到生成了对应的文件,文件内容就是规则信息:

    2.2、Push模式持久化

    该模式需同时改造sentinel控制台和自己的应用。

    2.2.1、控制台改造

    2.2.1.1、下载sentinel源码

    https://github.com/alibaba/Sentinel

    2.2.1.2、修改原sentinel-dashboard项目下的POM文件
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        <!--scope>test</scope-->
    </dependency>        

    注释掉scope

    2.2.1.3、复制sentinel-dashboard项目下test中的nacos代码

    src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos到src/main/java/com/alibaba/csp/sentinel/dashboard/rule下

    2.2.1.4、修改NacosConfig中的nacos服务地址
    com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfig:
    @Bean
    public ConfigService nacosConfigService() throws Exception {
        return ConfigFactory.createConfigService("localhost:8848");
    }
    2.2.1.5、修改FlowControllerV2中的ruleProvider和rulePublisher

    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;
    2.2.1.6、sidebar.html流控规则路由从dashboard.flowV1改成dashboard.flow

    sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html:

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

    注意:在该页面添加规则与在簇点链路页面添加流控规则不是同一页面,簇点链路页面添加规则需另行改造。

    2.2.1.7、其他规则改造

    上面的步骤只是改造了流控规则,其他的规则可用参考流控规则进行改造。

    2.2.2、应用改造

    2.2.2.1、引入依赖
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        <version>1.8.0</version>
    </dependency>            
    2.2.2.2、增加规则数据源配置
    spring:
      cloud:
        sentinel:
          transport:
            port: 8719
            dashboard: 10.49.196.10:8080
          datasource:
            flow:
              nacos:
                server-addr: 10.49.196.10:8848
                dataId: ${spring.application.name}-flow-rules
                groupId: SENTINEL_GROUP
                rule-type: flow
            degrade:
              nacos:
                server-addr: 10.49.196.10:8848
                dataId: ${spring.application.name}-degrade-rules
                groupId: SENTINEL_GROUP
                rule-type: degrade

    这边只配置了流控及降级的数据源,其他规则类似配置。

    2.2.3、验证

    启动nacos、sentinel控制台及应用,在sentinel配置规则后,在nacos控制台中可以看到对应的配置,配置内容就是规则信息:

  • 相关阅读:
    我是怎么做App token认证的
    APP和服务端-架构设计(二)
    APP和服务端-架构设计(一)
    拦截和跟踪HTTP请求的主要方法及实现
    权限控制方案之——基于URL拦截
    你真的会用Retrofit2吗?Retrofit2完全教程
    科学的解决Http Token拦截器TokenInterceptor实现
    谈谈敏捷开发(转)
    Modbus TCP 示例报文
    Modbus 通信协议详解
  • 原文地址:https://www.cnblogs.com/wuyongyin/p/13794559.html
Copyright © 2011-2022 走看看