让sentinel-dashboard的流控配置持久化到nacos

本文介绍如何将Sentinel Dashboard的流控配置同步到Nacos,实现配置的持久化。通过修改Sentinel Dashboard代码,使其在修改规则时能自动发布到Nacos,微服务重启后可从Nacos读取最新配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

让sentinel-dashboard的流控配置持久化到nacos

 

官网 git: https://github.com/alibaba/Sentinel

微服务可以将流控配置放在nacos中,但dashboard修改的规则不能持久化。

本文将dashboard中的修改同步到nacos中,dashboard监控流控仍然从微服务客户端读取。

微服务客户端重启后会从nacos中读取数据,实现持久化。

 

主要思路: dashboard修改配置的时候,将数据发布到nacos中。注意dashboard中的是xxRuleEntity,而客户端读取nacos的是xxRule.

 

master分支 目前为sentinel-1.8.0为例

下载源码,idea打开。

找到sentinel-dashboard这个项目

在该项目下的pom.xml文件中找到:

      <!-- for Nacos rule publisher sample -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <scope>test</scope>
        </dependency>

将<scope>test</scope>注释掉。

 

展开test->java->com.alibaba.csp.sentinel.dashboard->rule->nacos

复制到src->java->com.alibaba.csp.sentinel.dashboard

 

1. 主要文件

NacosCofig 服务配置 及convert

​
@Configuration
public class NacosConfig {

    @Value("${sentinel.datasource.nacos.server-addr:localhost:8848}")
    private String serverAddr;

    @Value("${sentinel.datasource.nacos.enable:false}")
    private boolean enable;

    @Bean
    public FlowRuleConvert flowRuleEntityEncoder() {
        return new FlowRuleConvert();
    }

    @Bean
    public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
        return s -> JSON.parseArray(s, FlowRuleEntity.class);
    }

    @Bean
    public ParamFlowRuleConvert paramFlowRuleEntityEncoder() {
        return new ParamFlowRuleConvert();
    }

    @Bean
    public Converter<String, List<ParamFlowRuleEntity>> paramFlowRuleEntityDecoder() {
        return s -> JSON.parseArray(s, ParamFlowRuleEntity.class);
    }



    @Bean
    public DegradeRuleConvert degradeRuleEntityEncoder() {
        return new DegradeRuleConvert();
    }

    @Bean
    public Converter<String, List<DegradeRuleEntity>> degradeRuleEntityDecoder() {
        return s -> JSON.parseArray(s, DegradeRuleEntity.class);
    }

    @Bean
    public ConfigService nacosConfigService() throws Exception {
        return ConfigFactory.createConfigService(serverAddr);
    }


    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }
}

​

默认配置 NacosConfigUtil

注意 GROUP_ID 、xx_DATA_ID_POSTFIX 需要微服务客户端的一致

public final class NacosConfigUtil {

//    public static final String GROUP_ID = "SENTINEL_GROUP";
    public static final String GROUP_ID = "DEFAULT_GROUP";

    public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
    public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";
    public static final String DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";
    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() {}
}

FlowRuleNacosPublisher 规则发布

@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {

    @Autowired
    private ConfigService configService;
    @Autowired
    private FlowRuleConvert converter;

    @Override
    public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        boolean success = configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
            NacosConfigUtil.GROUP_ID, converter.convert(rules));
        if(!success){
            throw new RuntimeException("publish to nacos fail");
        }
    }
}

 

ParamFlowRuleNacosPublisher


@Component("paramFlowRuleNacosPublisher")
public class ParamFlowRuleNacosPublisher implements DynamicRulePublisher<List<ParamFlowRuleEntity>> {

    @Autowired
    private ConfigService configService;
    @Autowired
    private ParamFlowRuleConvert converter;

    @Override
    public void publish(String app, List<ParamFlowRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        boolean success = configService.publishConfig(app + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
            NacosConfigUtil.GROUP_ID, converter.convert(rules));
        if(!success){
            throw new RuntimeException("publish to nacos fail");
        }
    }
}

DegradeRuleNacosPublisher


@Component("degradeRuleNacosPublisher")
public class DegradeRuleNacosPublisher implements DynamicRulePublisher<List<DegradeRuleEntity>> {

    @Autowired
    private ConfigService configService;
    @Autowired
    private DegradeRuleConvert converter;

    @Override
    public void publish(String app, List<DegradeRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        boolean success = configService.publishConfig(app + NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
            NacosConfigUtil.GROUP_ID, converter.convert(rules));

        if(!success){
            throw new RuntimeException("publish to nacos fail");
        }
    }
}

2. 转换类

FlowRuleConvert

public class FlowRuleConvert implements Converter<List<FlowRuleEntity>, String> {

    @Override
    public String convert(List<FlowRuleEntity> flowRuleEntities) {
        if(flowRuleEntities==null){
            return null;
        }
        List<FlowRule> flowRules = new ArrayList<>();
        for (FlowRuleEntity entity : flowRuleEntities) {
            FlowRule rule = new FlowRule();
            rule.setLimitApp(entity.getLimitApp());
            rule.setResource(entity.getResource());
            if(entity.getGmtCreate()!=null){
                rule.setGrade(entity.getGrade());
            }
            if(entity.getCount()!=null){
                rule.setCount(entity.getCount());
            }
            if(entity.getStrategy()!=null){
                rule.setStrategy(entity.getStrategy());
            }
            rule.setRefResource(entity.getRefResource());
            if(entity.getControlBehavior()!=null){
                rule.setControlBehavior(entity.getControlBehavior());
            }
            if(entity.getWarmUpPeriodSec()!=null){
                rule.setWarmUpPeriodSec(entity.getWarmUpPeriodSec());
            }
            if(entity.getMaxQueueingTimeMs()!=null){
                rule.setMaxQueueingTimeMs(entity.getMaxQueueingTimeMs());
            }
            rule.setClusterMode(entity.isClusterMode());
            rule.setClusterConfig(entity.getClusterConfig());

            flowRules.add(rule);
        }
        return JSON.toJSONString(flowRules,true);
    }
}

ParamFlowRuleConvert

DegradeRuleConvert


@Autowired
private NacosConfig nacosConfig;

@Autowired
private FlowRuleNacosPublisher flowRuleNacosPublisher;

/** 修改publish **/
private CompletableFuture<Void> publishRules(String app, String ip, Integer port) throws Exception {
    List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
    if(nacosConfig.isEnable()){
        flowRuleNacosPublisher.publish(app,rules);
    }
    return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules);
}

ParamFlowRuleController

@Autowired
private NacosConfig nacosConfig;

@Autowired
private ParamFlowRuleNacosPublisher paramFlowRuleNacosPublisher;

private CompletableFuture<Void> publishRules(String app, String ip, Integer port) throws Exception {
    List<ParamFlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
    if(nacosConfig.isEnable()){
        paramFlowRuleNacosPublisher.publish(app,rules);
    }
    return sentinelApiClient.setParamFlowRuleOfMachine(app, ip, port, rules);
}

DegradeController

 


@Autowired
private NacosConfig nacosConfig;

@Autowired
private DegradeRuleNacosPublisher degradeRuleNacosPublisher;

private boolean publishRules(String app, String ip, Integer port) {
    List<DegradeRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
    if(nacosConfig.isEnable()){
        try {
            degradeRuleNacosPublisher.publish(app,rules);
        } catch (Exception e) {
            logger.error("publishRules failed. ",e);
            return false;
        }
    }
    return sentinelApiClient.setDegradeRuleOfMachine(app, ip, port, rules);
}

4. 配置文件

# nacos 配置开关 默认false
sentinel.datasource.nacos.enable=true
# nacos 地址 默认 localhost:8848
sentinel.datasource.nacos.server-addr=localhost:8848

5 微服务端示例

配置文件

server:
  port: 8081
spring:
  application:
    name: sentinel-spring-cloud-nacos
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
      eager: false
      # sentinel nacos
      datasource:
        ds-flow:
          nacos:
            server-addr: 192.168.116.128:8848
            dataId: ${spring.application.name}-flow-rules
            groupId: DEFAULT_GROUP
            dataType: json
            rule-type: flow
        ds-param:
          nacos:
            server-addr: 192.168.116.128:8848
            dataId: ${spring.application.name}-param-rules
            groupId: DEFAULT_GROUP
            dataType: json
            rule-type: param-flow
        ds-degrade:
          nacos:
            server-addr: 192.168.116.128:8848
            dataId: ${spring.application.name}-degrade-rules
            groupId: DEFAULT_GROUP
            dataType: json
            rule-type: degrade

SentinelResource

@RestController
@RequestMapping("/api/sentinel")
public class SentinelDemoController {

    @SentinelResource(value = "helloSentinel",blockHandler = "blockHandler",blockHandlerClass = SentinelBlockUtil.class )
    @GetMapping("/helloSentinel")
    public Object helloSentinel(){
        return "hello sentinel. "+System.currentTimeMillis();
    }


    @SentinelResource(value = "helloSentinelParam",blockHandler = "oneParamBlockHandler",blockHandlerClass = SentinelBlockUtil.class)
    @GetMapping("/helloSentinelParam")
    public Object helloSentinelParam(String userId){
        String data = "hello helloSentinelParam. userId:"+userId+"  "+System.currentTimeMillis();
        return data;
    }
}

 

源码:https://github.com/lvzhyt/Sentinel/tree/dashboard-nacos

dashboard-nacos 分支 sentinel-dashboard

微服务客户端示例 sentinel-demo-spring-cloud-nacos

 

 

 

 

<think>嗯,用户遇到了Sentinel Dashboard 1.8.4和Nacos集成时规则不生效的问题。我需要帮他们找出可能的原因和解决方案。首先,我需要回顾一下SentinelNacos集成的机制。根据引用内容,用户修改了Sentinel Dashboard的源码来实现规则持久化Nacos,主要是规则。那可能的问题点在哪里呢? 首先,配置同步是否正确?用户需要检查Nacos配置是否被正确创建。比如,在Dashboard添加规则后,Nacos中应该生成对应的配置文件,如xxx-sentinel-flow-rules。如果这一步没发生,可能是DashboardNacos的推送有问题。这时候要确认Nacos的地址、端口和命名空间是否正确,引用[5]提到了nacos.address和nacos.namespace的配置,用户需要检查这些参数是否正确设置,尤其是命名空间是否存在。 其次,客户端应用是否配置正确。即使Dashboard成功将规则推送到Nacos,客户端应用也需要正确连接到Nacos来获取规则。客户端需要引入sentinel-datasource-nacos依赖,并且在配置文件中指定Nacos的服务器地址、dataId、groupId等。如果这里的配置有误,比如dataId不匹配,客户端可能无法读取规则。例如,dataId通常是${spring.application.name}-sentinel-flow-rules,需要和Dashboard推送时生成的一致。 另外,权限问题也不容忽视。Nacos的访问可能需要用户名和密码,尤其是在生产环境中。如果客户端应用或Dashboard没有正确配置认证信息,可能导致连接失败。用户需要检查是否在配置中加入了nacos.username和nacos.password,特别是在Nacos开启了认证的情况下。 还有,版本兼容性也是一个潜在的问题。Sentinel 1.8.4和Nacos客户端的版本是否兼容?如果使用的Nacos客户端版本过旧或过新,可能会导致兼容性问题。用户应确认使用的依赖版本是否匹配,比如引用中提到的是sentinel-datasource-nacos的版本是否与Sentinel核心库一致。 日志分析同样重要。查看Sentinel Dashboard和客户端的日志,是否有错误信息。例如,推送规则到Nacos时是否抛出异常,或者客户端拉取配置时是否报错。根据引用[4],配置推送程可能涉及多个步骤,任何一个环节出错都可能导致规则不生效。 最后,如果以上步骤都确认无误,可能需要检查Nacos服务器本身的状态,比如是否运行正常,网络是否可达,存储是否有问题。另外,重启相关服务,如Dashboard和客户端应用,有时候配置可能需要重新加载才能生效。 总结下来,可能的解决步骤包括检查配置同步、客户端配置、权限设置、版本兼容性、日志排查以及Nacos服务器状态。用户需要逐一排查这些方面,找到导致规则不生效的具体原因,并进行相应的调整。</think>### Sentinel-Dashboard 1.8.4与Nacos规则不生效的解决方案 #### 1. 确认配置同步- **问题定位**:检查Sentinel Dashboard推送规则到Nacos配置是否生效。若制台添加规则后,Nacos未生成对应的配置文件(如`xxx-sentinel-flow-rules`),则说明同步程异常[^1][^4]。 - **解决方案**: - 验证Nacos地址和命名空间配置是否正确,确保`nacos.address`和`nacos.namespace`在`application.properties`中配置无误[^5]。 - 检查Sentinel Dashboard的源码修改部分,确认已正确集成Nacos数据源(需覆盖`FlowControllerV2`类并注入`NacosConfigService`)[^2][^4]。 #### 2. 客户端应用配置验证 - **问题定位**:若Nacos已生成配置文件,但客户端未加载规则,可能是客户端未正确配置Nacos数据源。 - **解决方案**: - 在客户端应用的配置文件中添加Nacos数据源配置: ```yaml spring: cloud: sentinel: datasource: flow: nacos: server-addr: ${nacos.address} dataId: ${spring.application.name}-sentinel-flow-rules groupId: DEFAULT_GROUP rule-type: flow ``` - 确保客户端引入依赖`com.alibaba.csp:sentinel-datasource-nacos`且版本与Sentinel核心库(1.8.4)兼容[^3]。 #### 3. 权限与网络问题排查 - **问题定位**:Nacos访问权限或网络不通可能导致规则推送失败。 - **解决方案**: -Nacos开启鉴权,需在Sentinel Dashboard和客户端配置用户名/密码。 - 使用`telnet`或`curl`验证Nacos服务端可连通性。 #### 4. 日志分析与调试 - **问题定位**:通过日志定位具体错误(如规则推送异常或客户端拉取失败)。 - **解决方案**: - 查看Sentinel Dashboard日志,确认推送Nacos时是否报错(如`Failed to push rules to Nacos`)。 - 检查客户端启动日志,确认是否成功加载Nacos中的规则配置。 #### 5. 重启验证 完成上述配置后,**重启Sentinel Dashboard和客户端应用**,重新添加规则观察是否持久化生效[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值