准备工作:
一:修改pom.xml中的sentinel-datasource-nacos的依赖,将test注释掉,这样才能在主程序中使用。
com.alibaba.csp
sentinel-datasource-nacos
二:找到resources/app/scripts/directives/sidebar/sidebar.html中的这段代码:
流控规则
修改为:
流控规则
这样修改之后就会跳转到FlowControllerV2的接口。
三:再项目com.alibaba.csp.sentinel.dashboard中新建一个nacos包来实现扩展功能。
@Component
@ConfigurationProperties(prefix = "nacos.server")
public class NacosConfigProperties {
private String ip;
private String port;
private String namespace;
private String groupId;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getServerAddr() {
return this.getIp()+":"+this.getPort();
}
@Override
public String toString() {
return "NacosConfigProperties [ip=" + ip + ", port=" + port + ", namespace="
+ namespace + ", groupId=" + groupId + "]";
}
}
public final class NacosConfigConstant {
public static final String FLOW_DATA_ID_POSTFIX = "-sentinel-flow";
public static final String GROUP_ID = "DEFAULT_GROUP";
}
@Configuration
public class NacosConfig {
@Autowired
private NacosConfigProperties nacosConfigProperties;
/**
* 非常关键 这里将FlowRuleEntity转换成FlowRule才会对客户端生效
* @return FlowRule
*/
@Bean
public Converter, String> flowRuleEntityEncoder() {
return rules -> JSON.toJSONString(rules.stream().map(FlowRuleEntity::toRule).collect(Collectors.toList()), true);
}
@Bean
public Converter> flowRuleEntityDecoder() {
return s -> JSON.parseArray(s, FlowRuleEntity.class);
}
@Bean
public ConfigService nacosConfigService() throws Exception {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, nacosConfigProperties.getServerAddr());
properties.put(PropertyKeyConst.NAMESPACE, nacosConfigProperties.getNamespace());
return ConfigFactory.createConfigService(properties);
}
}
四:编写动态推拉模式的扩展代码
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider> {
private static Logger logger = LoggerFactory.getLogger(FlowRuleNacosProvider.class);
@Autowired
private NacosConfigProperties nacosConfigProperties;
@Autowired
private ConfigService configService;
@Autowired
private Converter> converter;
@Override
public List getRules(String appName) throws Exception {
String rules = configService.getConfig(appName + NacosConfigConstant.FLOW_DATA_ID_POSTFIX, nacosConfigProperties.getGroupId(), 3000);
logger.info("从Nacos中拉取到限流规则信息:{}",rules);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher> {
@Autowired
private NacosConfigProperties nacosConfigProperties;
@Autowired
private ConfigService configService;
@Autowired
private Converter, String> converter;
@Override
public void publish(String app, List rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + NacosConfigConstant.FLOW_DATA_ID_POSTFIX, nacosConfigProperties.getGroupId(), converter.convert(rules));
}
}
五:然后将FlowControllerV2中的默认DynamicRuleProvider和DynamicRulePublisher修改为:
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher> rulePublisher;
private void publishRules(/*@NonNull*/ String app) throws Exception {
List rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
logger.info("添加限流规则成功{}", JSON.toJSONString(rules.stream().map(FlowRuleEntity::toRule).collect(Collectors.toList()), true));
}
六:application.properties配置文件
#nacos
nacos.server.ip=localhost
nacos.server.port=8848
nacos.server.namespace=
nacos.server.group-id=DEFAULT_GROUP