生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了:
但是官网提供的Sentinel 控制台jar包是不可以直接和nacos互通的需要修改才行。
pom文件改造
修改pom.xml 将原来的这句话覆盖掉。原来有个 test。这个要去掉。
<!-- for Nacos rule publisher sample -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
Sentinel 控制台改造
1、在rule包下面新建Nacos包然后再这个包下面新建文件
2、新建NacosPropertiesConfiguration类
package com.alibaba.csp.sentinel.dashboard.rule.Nacos;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "sentinel.nacos")
@Data
public class NacosPropertiesConfiguration {
public String serverAddr;
public String dataId;
public String groupId = "DEFAULT_GROUP";
public String namespace;
}
3、新建NacosConstants
public class NacosConstants {
public static final String DATA_ID_POSTFIX = "-sentinel-flow";
public static final String GROUP_ID = "Sentinel_Demo";
}
4、新建NacosConfiguration类
package com.alibaba.csp.sentinel.dashboard.rule.Nacos;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
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;
@EnableConfigurationProperties(NacosPropertiesConfiguration.class)
@Configuration
public class NacosConfiguration {
@Bean
public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
return s -> JSON.parseArray(s, FlowRuleEntity.class);
}
@Bean
public ConfigService nacosConfigService(NacosPropertiesConfiguration nacosPropertiesConfiguration) throws Exception {
return NacosFactory.createConfigService("localhost:8848");
}
}
5、新建FlowRuleNacosPublisher类
package com.alibaba.csp.sentinel.dashboard.rule.Nacos;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private NacosPropertiesConfiguration nacosPropertiesConfiguration;
@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 cannot be empty");
if (rules == null) {
return;
}
String dataId = new StringBuilder(app).append(NacosConstants.DATA_ID_POSTFIX).toString();
configService.publishConfig(dataId, nacosPropertiesConfiguration.getGroupId(), converter.convert(rules));
}
}
6、新建FlowRuleNacosProvider
package com.alibaba.csp.sentinel.dashboard.rule.Nacos;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
private static final Logger logger = LoggerFactory.getLogger(FlowRuleNacosProvider.class);
@Autowired
private NacosPropertiesConfiguration nacosPropertiesConfiguration;
@Autowired
private ConfigService configService;
@Autowired
private Converter<String, List<FlowRuleEntity>> converter;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
String dataId = new StringBuilder(appName).append(NacosConstants.DATA_ID_POSTFIX).toString();
String rules = configService.getConfig(dataId, nacosPropertiesConfiguration.getGroupId(), 3000);
logger.info("pull flow rule from Nacos Config: {}", rules);
if (StringUtils.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
7、修改FlowControllerV2
将这三句代码覆盖原来的三句
@Autowired
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
8、修改前台html文件。html文件原来是走的v1版本
将sidebar.html gatewayFlowV1 的V1去掉。
9、重新启动