【微服务专题】深入理解与实践微服务架构(二十)之Sentinel数据双向同步(2)

1,069 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

2. 后端代码修改

① 配置类修改

直接在com.alibaba.csp.sentinel.dashboard.rule.nacos包下创建以下类:

image-20220720200407603

NacosPropertiesConfig

NacosPropertiesConfig,存放前面配置文件中,关于Nacos的配置:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;
​
import org.springframework.boot.context.properties.ConfigurationProperties;
​
/**
 * Created by deepinsea on 2022/7/19.
 * Nacos配置属性类
 */
@ConfigurationProperties("sentinel.nacos")
public class NacosPropertiesConfig {
    private String serverAddr;
    private String dataId;
    private String groupId = "SENTINEL_GROUP"; // 默认分组
    private String namespace;
​
    public String getServerAddr() {
        return serverAddr;
    }
​
    public void setServerAddr(String serverAddr) {
        this.serverAddr = serverAddr;
    }
​
    public String getDataId() {
        return dataId;
    }
​
    public void setDataId(String dataId) {
        this.dataId = dataId;
    }
​
    public String getGroupId() {
        return groupId;
    }
​
    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }
​
    public String getNamespace() {
        return namespace;
    }
​
    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }
}

这里可以不用创建这个配置文件,也可以直接通过@Value的方式读取properties配置文件中的参数到NacosConfg中,但是这种方式更容易管理配置信息。在参数较多的配置读取上更解耦,并且有着管理上的优势。

NacosConfigUtil

NacosConfigUtil,存放一些常量和各种规则文件名后缀:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;
​
/**
 * Created by deepinsea on 2022/7/19.
 * Nacos配置参数工具
 */
public final class NacosConfigUtil {
​
    public static final String GROUP_ID = "SENTINEL_GROUP"; // sentinel中创建规则默认为SENTINEL_GROUP,推荐这种方式
//    public static final String GROUP_ID = "DEFAULT_GROUP"; // nacos中创建的规则默认为DEFAULT_GROUP(建议区分开)
​
    public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
    public static final String DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";
    public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";
    public static final String SYS_DATA_ID_POSTFIX = "-system-rules";
    public static final String AUTH_DATA_ID_POSTFIX = "-auth-rules";
​
    public static final String GATEWAY_FLOW_DATA_ID_POSTFIX = "-gateway-flow-rules";
    public static final String GATEWAY_API_DATA_ID_POSTFIX = "-gateway-api-groups";
​
    public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";
​
    /**
     * cc for `cluster-client`
     */
    public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";
    /**
     * cs for `cluster-server`
     */
    public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";
    public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";
    public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";
​
    private NacosConfigUtil() {}
}
NacosConfig

NacosConfig ,用于读取Nacos属性配置读取和Nacos中的Sentinel规则格式转换(序列化):

/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.csp.sentinel.dashboard.rule.nacos;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.*;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
import java.util.List;
import java.util.Properties;
​
/**
 * Created by deepinsea on 2022/7/19.
 * Nacos属性读取和Nacos-Sentinel规则转换配置类
 */
@EnableConfigurationProperties(NacosPropertiesConfig.class)
@Configuration
public class NacosConfig {
​
    // 流控规则 Converter
    @Bean
    public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
        return JSON::toJSONString;
    }
​
    @Bean
    public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
        return s -> JSON.parseArray(s, FlowRuleEntity.class);
    }
​
    // 降级规则 Converter
    @Bean
    public Converter<List<DegradeRuleEntity>, String> degradeRuleEntityEncoder() {
        return JSON::toJSONString;
    }
​
    @Bean
    public Converter<String, List<DegradeRuleEntity>> degradeRuleEntityDecoder() {
        return s -> JSON.parseArray(s, DegradeRuleEntity.class);
    }
​
    // 热点规则 Converter
    @Bean
    public Converter<List<ParamFlowRuleEntity>, String> paramsRuleEntityEncoder() {
        return JSON::toJSONString;
    }
​
    @Bean
    public Converter<String, List<ParamFlowRuleEntity>> paramsRuleEntityDecoder() {
        return s -> JSON.parseArray(s, ParamFlowRuleEntity.class);
    }
​
    // 系统规则 Converter
    @Bean
    public Converter<List<SystemRuleEntity>, String> systemRuleEntityEncoder() {
        return JSON::toJSONString;
    }
​
    @Bean
    public Converter<String, List<SystemRuleEntity>> systemRuleEntityDecoder() {
        return s -> JSON.parseArray(s, SystemRuleEntity.class);
    }
​
    // 授权规则 Converter
    @Bean
    public Converter<List<AuthorityRuleEntity>, String> authRuleEntityEncoder() {
        return JSON::toJSONString;
    }
​
​
    @Bean
    Converter<String, List<AuthorityRuleEntity>> authRuleEntityDecoder() {
        return s -> JSON.parseArray(s, AuthorityRuleEntity.class);
    }
​
    // 网关限流规则 Converter
    @Bean
    public Converter<List<GatewayFlowRuleEntity>, String> gatewayFlowRuleEntityEncoder() {
        return JSON::toJSONString;
    }
​
​
    @Bean
    Converter<String, List<GatewayFlowRuleEntity>> gatewayFlowRuleEntityDecoder() {
        return s -> JSON.parseArray(s, GatewayFlowRuleEntity.class);
    }
​
    // 网关API限流规则 Converter
    @Bean
    public Converter<List<ApiDefinitionEntity>, String> gatewayApiRuleEntityEncoder() {
        return JSON::toJSONString;
    }
​
​
    @Bean
    Converter<String, List<ApiDefinitionEntity>> gatewayApiRuleEntityDecoder() {
        return s -> JSON.parseArray(s, ApiDefinitionEntity.class);
    }
​
    // 配置管理服务
    @Bean
    public ConfigService nacosConfigService(NacosPropertiesConfig nacosPropertiesConfig) throws Exception {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, nacosPropertiesConfig.getServerAddr());
        properties.put(PropertyKeyConst.NAMESPACE, nacosPropertiesConfig.getNamespace());
        return ConfigFactory.createConfigService(properties);
    }
}
② 创建规则交互层

包结构部分

新建包 com.alibaba.csp.sentinel.dashboard.rule.nacos,并在该包下根据以下结构新建包,下面进行多种规则的拉取和推送实现类将按照如下包结构进行创建:

├─authority #存放授权规则相关类
├─degrade #存放降级规则相关类
├─flow #存放限流规则相关类
├─gateway #存放网关限流规则相关类
│  ├─api
│  └─flow
├─param #存放热点规则相关类
└─system #存放系统规则相关类
授权规则拉取和推送类

authority 包下创建下面的规则拉取和推送实现类,下面同理

AuthorityRuleNacosProvider ,授权规则拉取实现类,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.authority;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 拉取Nacos中手动添加的Auth规则配置
 */
@Component("authRuleNacosProvider")
public class AuthorityRuleNacosProvider implements DynamicRuleProvider<List<AuthorityRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityRuleNacosProvider.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<AuthorityRuleEntity>> converter;
​
    @Override
    public List<AuthorityRuleEntity> getRules(String appName) throws Exception {
        String rules = configService.getConfig(appName + NacosConfigUtil.AUTH_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, 3000);
        LOGGER.info("get auth rule from nacos, rules : {}", rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return converter.convert(rules);
    }
}

AuthorityRuleNacosPublisher,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.authority;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 推送Auth规则到Nacos中
 */
@Component("authRuleNacosPublisher")
public class AuthorityRuleNacosPublisher implements DynamicRulePublisher<List<AuthorityRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityRuleNacosPublisher.class);
​
    @Autowired
    private ConfigService configService;
​
    @Autowired
    private Converter<List<AuthorityRuleEntity>, String> converter;
​
    @Override
    public void publish(String app, List<AuthorityRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        String convertedRule = converter.convert(rules);
        LOGGER.info("sentinel dashboard publisher auth rules : {}", convertedRule);
        configService.publishConfig(app + NacosConfigUtil.AUTH_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, convertedRule);
    }
}
降级规则拉取与推送类

为什么没有熔断类呢?因为熔断是降级状态的一种后置处理机制,因此Sentinel将降级和熔断合并为一个逻辑了

和前面一样,在前面创建的degrade包下创建以下两个类。

DegradeRuleNacosProvider,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 拉取Nacos中的Degrade规则配置到Sentinel
 */
@Component("degradeRuleNacosProvider")
public class DegradeRuleNacosProvider implements DynamicRuleProvider<List<DegradeRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(DegradeRuleNacosProvider.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<DegradeRuleEntity>> converter;
​
    @Override
    public List<DegradeRuleEntity> getRules(String appName) throws Exception {
        String rules = configService.getConfig(appName + NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, 3000);
        LOGGER.info("get degrade rules from nacos, rules: {}", rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return converter.convert(rules);
    }
}

DegradeRuleNacosPublisher,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 推送Sentinel中的Degrade规则配置到Nacos
 */
@Component("degradeRuleNacosPublisher")
public class DegradeRuleNacosPublisher implements DynamicRulePublisher<List<DegradeRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(DegradeRuleNacosPublisher.class);
​
    @Autowired
    private ConfigService configService;
​
    @Autowired
    private Converter<List<DegradeRuleEntity>, String> converter;
​
    @Override
    public void publish(String app, List<DegradeRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        String convertedRule = converter.convert(rules);
        LOGGER.info("sentinel dashboard publish degrade rules: {}", convertedRule);
        configService.publishConfig(app + NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, convertedRule);
    }
}
流控规则拉取与推送类

在前面创建的flow包下创建

FlowRuleNacosProvider,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.flow;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 拉取Nacos中的普通流控规则(flow)配置到Sentinel
 */
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(FlowRuleNacosProvider.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<FlowRuleEntity>> converter;
​
    @Override
    public List<FlowRuleEntity> getRules(String appName) throws Exception {
        String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, 3000);
        LOGGER.info("get flow rules from nacos, rules: {}", rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return converter.convert(rules);
    }
}

FlowRuleNacosPublisher,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.flow;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 推送Flow规则配置到Nacos
 */
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(FlowRuleNacosPublisher.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<List<FlowRuleEntity>, String> converter;
​
    @Override
    public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        String convertedRule = converter.convert(rules);
        LOGGER.info("sentinel dashboard publish flow rules: {}", convertedRule);
        configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, convertedRule);
    }
}
网关API分组拉取与推送类

在前面创建的gateway.api包下,创建API分组配置拉取和推送实现类

gatewayApiGroupNacosProvider,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.api;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 拉取Nacos中存储的Api分组配置信息
 */
@Component("gatewayApiRuleNacosProvider")
public class gatewayApiGroupNacosProvider implements DynamicRuleProvider<List<ApiDefinitionEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(gatewayApiGroupNacosProvider.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<ApiDefinitionEntity>> converter;
​
    @Override
    public List<ApiDefinitionEntity> getRules(String appName) throws Exception {
        String rules = configService.getConfig(appName + NacosConfigUtil.GATEWAY_API_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, 3000);
        LOGGER.info("get gateway api rules from nacos, rules: {}", rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return converter.convert(rules);
    }
}

gatewayApiGroupNacosPublisher,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.api;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 推送Api分组配置到Nacos
 */
@Component("gatewayApiRuleNacosPublisher")
public class gatewayApiGroupNacosPublisher implements DynamicRulePublisher<List<ApiDefinitionEntity>> {
    private static final Logger LOGGER = LoggerFactory.getLogger(gatewayApiGroupNacosPublisher.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<List<ApiDefinitionEntity>, String> converter;
​
    @Override
    public void publish(String app, List<ApiDefinitionEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        String convertedRule = converter.convert(rules);
        LOGGER.info("sentinel dashboard publish gateway api rules: {}", convertedRule);
        configService.publishConfig(app + NacosConfigUtil.GATEWAY_API_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, convertedRule);
    }
}
网关流控规则拉取与推送类

在gateway.flow包下,创建网关规则(v2版本的流控规则)拉取与推送实现类

GatewayFlowRuleNacosProvider,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.flow;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 拉取Nacos中存储的gateway-flow配置信息
 */
@Component("gatewayFlowRuleNacosProvider")
public class GatewayFlowRuleNacosProvider implements DynamicRuleProvider<List<GatewayFlowRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(GatewayFlowRuleNacosProvider.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<GatewayFlowRuleEntity>> converter;
​
    @Override
    public List<GatewayFlowRuleEntity> getRules(String appName) throws Exception {
        String rules = configService.getConfig(appName + NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, 3000);
        LOGGER.info("get gateway flow rules from nacos, rules: {}", rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return converter.convert(rules);
    }
}

GatewayFlowRuleNacosPublisher,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.flow;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 推送gateway-flow配置到Nacos
 */
@Component("gatewayFlowRuleNacosPublisher")
public class GatewayFlowRuleNacosPublisher implements DynamicRulePublisher<List<GatewayFlowRuleEntity>> {
    private static final Logger LOGGER = LoggerFactory.getLogger(GatewayFlowRuleNacosPublisher.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<List<GatewayFlowRuleEntity>, String> converter;
​
    @Override
    public void publish(String app, List<GatewayFlowRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        String convertedRule = converter.convert(rules);
        LOGGER.info("sentinel dashboard publish gateway flow rules: {}", convertedRule);
        configService.publishConfig(app + NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, convertedRule);
    }
}
热点规则拉取与推送类

在前面创建的param包下,新建热点(参数)规则拉取与推送实现类

ParamRuleNacosProvider,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.param;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 拉取Nacos的Param-Rule配置到Sentinel
 */
@Component("paramRuleNacosProvider")
public class ParamRuleNacosProvider implements DynamicRuleProvider<List<ParamFlowRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(ParamRuleNacosProvider.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<ParamFlowRuleEntity>> converter;
​
    @Override
    public List<ParamFlowRuleEntity> getRules(String appName) throws Exception {
        String rules = configService.getConfig(appName + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, 3000);
        LOGGER.info("get param rules from nacos, rules: {}", rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return converter.convert(rules);
    }
}

ParamRuleNacosPublisher,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.param;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 推送Sentinel的Param-Rule配置到Nacos
 */
@Component("paramRuleNacosPublisher")
public class ParamRuleNacosPublisher implements DynamicRulePublisher<List<ParamFlowRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(ParamRuleNacosPublisher.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<List<ParamFlowRuleEntity>, String> converter;
​
    @Override
    public void publish(String app, List<ParamFlowRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        String convertedRule = converter.convert(rules);
        LOGGER.info("sentinel dashboard publish param rules: {}", convertedRule);
        configService.publishConfig(app + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, convertedRule);
    }
​
}
系统规则拉取与推送类

在前面创建的system包下,新建系统规则拉取与推送类

SystemRuleNacosProvider,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.system;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 拉取System-Rule配置到Nacos
 */
@Component("systemRuleNacosProvider")
public class SystemRuleNacosProvider implements DynamicRuleProvider<List<SystemRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(SystemRuleNacosProvider.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<SystemRuleEntity>> converter;
​
    @Override
    public List<SystemRuleEntity> getRules(String appName) throws Exception {
        String rules = configService.getConfig(appName + NacosConfigUtil.SYS_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, 3000);
        LOGGER.info("get system rules from nacos, rules: {}", rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return converter.convert(rules);
    }
}

SystemRuleNacosPublisher,内容如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos.system;
​
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import java.util.List;
​
/**
 * Created by deepinsea on 2022/7/16.
 * 推送Sentinel的System-Rule配置到Nacos
 */
@Component("systemRuleNacosPublisher")
public class SystemRuleNacosPublisher implements DynamicRulePublisher<List<SystemRuleEntity>> {
​
    private static final Logger LOGGER = LoggerFactory.getLogger(SystemRuleNacosPublisher.class);
​
    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<List<SystemRuleEntity>, String> converter;
​
    @Override
    public void publish(String app, List<SystemRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        String convertedRule = converter.convert(rules);
        LOGGER.info("sentinel dashboard publisher system rule : {}", convertedRule);
        configService.publishConfig(app + NacosConfigUtil.SYS_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, convertedRule);
    }
}

到此,规则拉取与推送实现类已经全部编写完成了。

因为字数的限制,我们下一篇再对规则控制层进行改造。

欢迎点赞,谢谢各位大佬了ヾ(◍°∇°◍)ノ゙