sentinel 1.8. 2持久化Nacos动态规则热点规则和授权规则不生效的问题

sentinel 1.8.2 持久化Nacos动态规则热点规则和授权规则不生效的问题

问题:规则持久化到nacos之后,我在本地测试时候只有热点和授权规则不生效,我慢慢的在客户端sentinel-csp-nacos源码下然后推送之后BUG源码 一步一步查看,发现 ParamFlowRuleManager 类中map中一直没有规则,慢慢发现里面是实体类ParamFlowRule数据就是初始化类数据,这时候我继续看修改和查看 RulePropertyListener监听器 监听到了 但是在ParamFlowRuleManager.configUpdateconfigLoad 方法中buildParamRuleMap时候一直返回数据为空。这时候我觉得是不是版本有问题,当时的时候控制台1.8.0版本,

客户端是1.7.1版本,这时候我更换了本地客户端所有的cloudAlibaba boot sentinel 版本。发现还是失效,这时候我就拿出来nacos里面数据结构和客户端数据结构对比。数据结构不一致。查看sentinel-dashboard在自定义ParamFlowRuleNacosPublisher时候 推送的数据是ParamFlowRuleEntity。 客户端接收的ParamFlowRule类。这时候就需要改一下。

接下来~~~~~~~~~~~~~~~~~~~~~~~~开始

解决方案:

重写ParamFlowRuleEntity与AuthorityRuleEntity

1.热点参数规则

第一步重写ParamFlowRuleEntity
import com.alibaba.csp.sentinel.slots.block.Rule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowClusterConfig;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
 
import java.util.*;
 
/**
 * @author 阿志有点坑
 * @description
 * @date 2021/2/4 10:04
 */
public class ParamFlowRuleCorrectEntity implements RuleEntity {
 
    private Long id;
    private String app;
    private String ip;
    private Integer port;
    private String limitApp;
    private String resource;
    private Date gmtCreate;
 
    private int grade = 1;
    private Integer paramIdx;
    private double count;
    private int controlBehavior = 0;
    private int maxQueueingTimeMs = 0;
    private int burstCount = 0;
    private long durationInSec = 1L;
    private List<ParamFlowItem> paramFlowItemList = new ArrayList();
    private Map<Object, Integer> hotItems = new HashMap();
    private boolean clusterMode = false;
    private ParamFlowClusterConfig clusterConfig;
 
    public int getGrade() {
        return grade;
    }
 
    public void setGrade(int grade) {
        this.grade = grade;
    }
 
    public Integer getParamIdx() {
        return paramIdx;
    }
 
    public void setParamIdx(Integer paramIdx) {
        this.paramIdx = paramIdx;
    }
 
    public double getCount() {
        return count;
    }
 
    public void setCount(double count) {
        this.count = count;
    }
 
    public int getControlBehavior() {
        return controlBehavior;
    }
 
    public void setControlBehavior(int controlBehavior) {
        this.controlBehavior = controlBehavior;
    }
 
    public int getMaxQueueingTimeMs() {
        return maxQueueingTimeMs;
    }
 
    public void setMaxQueueingTimeMs(int maxQueueingTimeMs) {
        this.maxQueueingTimeMs = maxQueueingTimeMs;
    }
 
    public int getBurstCount() {
        return burstCount;
    }
 
    public void setBurstCount(int burstCount) {
        this.burstCount = burstCount;
    }
 
    public long getDurationInSec() {
        return durationInSec;
    }
 
    public void setDurationInSec(long durationInSec) {
        this.durationInSec = durationInSec;
    }
 
    public List<ParamFlowItem> getParamFlowItemList() {
        return paramFlowItemList;
    }
 
    public void setParamFlowItemList(List<ParamFlowItem> paramFlowItemList) {
        this.paramFlowItemList = paramFlowItemList;
    }
 
    public Map<Object, Integer> getHotItems() {
        return hotItems;
    }
 
    public void setHotItems(Map<Object, Integer> hotItems) {
        this.hotItems = hotItems;
    }
 
    public boolean isClusterMode() {
        return clusterMode;
    }
 
    public void setClusterMode(boolean clusterMode) {
        this.clusterMode = clusterMode;
    }
 
    public ParamFlowClusterConfig getClusterConfig() {
        return clusterConfig;
    }
 
    public void setClusterConfig(ParamFlowClusterConfig clusterConfig) {
        this.clusterConfig = clusterConfig;
    }
 
    @Override
    public Date getGmtCreate() {
        return gmtCreate;
    }
 
    public void setGmtCreate(Date gmtCreate) {
        this.gmtCreate = gmtCreate;
    }
 
    @Override
    public Long getId() {
        return id;
    }
 
    @Override
    public void setId(Long id) {
        this.id = id;
    }
 
    @Override
    public String getApp() {
        return app;
    }
 
    public void setApp(String app) {
        this.app = app;
    }
 
    @Override
    public String getIp() {
        return ip;
    }
 
    public void setIp(String ip) {
        this.ip = ip;
    }
 
    @Override
    public Integer getPort() {
        return port;
    }
 
    public void setPort(Integer port) {
        this.port = port;
    }
 
    public String getLimitApp() {
        return limitApp;
    }
 
    public void setLimitApp(String limitApp) {
        this.limitApp = limitApp;
    }
 
    public String getResource() {
        return resource;
    }
 
    public void setResource(String resource) {
        this.resource = resource;
    }
 
    @Override
    public Rule toRule(){
        ParamFlowRule rule=new ParamFlowRule();
        return rule;
    }
}
 
第二步:在NacosConfig添加对应的类型转换配置
@Bean
public Converter<List<ParamFlowRuleCorrectEntity>, String> paramFlowRuleCorrectEntityEncoder() {
    return JSON::toJSONString;
}
 
@Bean
public Converter<String, List<ParamFlowRuleCorrectEntity>> paramFlowRuleCorrectEntityDecoder() {
    return s -> JSON.parseArray(s, ParamFlowRuleCorrectEntity.class);
}
第三步:修改对应的ParamFlowRuleNacosProvider

package com.alibaba.csp.sentinel.dashboard.rule.nacos.param;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleCorrectEntity;
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.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 阿志有点坑
 * @since 1.4.0
 */
@Component("paramFlowRuleNacosProvider")
public class ParamFlowRuleNacosProvider implements DynamicRuleProvider<List<ParamFlowRuleEntity>> {

    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<String, List<ParamFlowRuleCorrectEntity>> 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);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        List<ParamFlowRuleCorrectEntity> entityList = converter.convert(rules);
        entityList.forEach(e -> e.setApp(appName));
        return entityList.stream().map(rule -> {
            ParamFlowRule paramFlowRule = new ParamFlowRule();
            BeanUtils.copyProperties(rule, paramFlowRule);
            ParamFlowRuleEntity entity = ParamFlowRuleEntity.fromParamFlowRule(rule.getApp(), rule.getIp(), rule.getPort(), paramFlowRule);
            entity.setId(rule.getId());
            entity.setGmtCreate(rule.getGmtCreate());
            return entity;
        }).collect(Collectors.toList());

    }
}
第四步:修改对应的NacosPublisher
/*
 * 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.param;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleCorrectEntity;
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.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Eric Zhao
 * @since 1.4.0
 */
@Component("paramFlowRuleNacosPublisher")
public class ParamFlowRuleNacosPublisher implements DynamicRulePublisher<List<ParamFlowRuleEntity>> {

    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<List<ParamFlowRuleCorrectEntity>, 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;
        }
        rules.forEach(e -> e.setApp(app));

        //  转换
        List<ParamFlowRuleCorrectEntity> list = rules.stream().map(rule -> {
            ParamFlowRuleCorrectEntity entity = new ParamFlowRuleCorrectEntity();
            BeanUtils.copyProperties(rule, entity);
            return entity;
        }).collect(Collectors.toList());

        configService.publishConfig(app + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
                NacosConfigUtil.GROUP_ID, converter.convert(list));
    }

}

授权规则也一样.

2.权限规则

第一步:重写AuthorityRuleEntity
package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule;

import com.alibaba.csp.sentinel.slots.block.Rule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;

import java.util.Date;

/**

- @author chengmeng

- @description

- @date 2021/2/4 14:08
  */
  public class AuthorityRuleCorrectEntity implements RuleEntity{

  private Long id;
  private String app;
  private String ip;
  private Integer port;
  private String limitApp;
  private String resource;
  private Date gmtCreate;
  private Date gmtModified;

  private int strategy;

  @Override
  public Long getId() {
      return id;
  }

  @Override
  public void setId(Long id) {
      this.id = id;
  }

  @Override
  public String getApp() {
      return app;
  }

  public void setApp(String app) {
      this.app = app;
  }

  @Override
  public String getIp() {
      return ip;
  }

  public void setIp(String ip) {
      this.ip = ip;
  }

  @Override
  public Integer getPort() {
      return port;
  }

  public void setPort(Integer port) {
      this.port = port;
  }

  public String getLimitApp() {
      return limitApp;
  }

  public void setLimitApp(String limitApp) {
      this.limitApp = limitApp;
  }

  public String getResource() {
      return resource;
  }

  public void setResource(String resource) {
      this.resource = resource;
  }

  @Override
  public Date getGmtCreate() {
      return gmtCreate;
  }

  public void setGmtCreate(Date gmtCreate) {
      this.gmtCreate = gmtCreate;
  }

  public Date getGmtModified() {
      return gmtModified;
  }

  public void setGmtModified(Date gmtModified) {
      this.gmtModified = gmtModified;
  }

  public int getStrategy() {
      return strategy;
  }

  public void setStrategy(int strategy) {
      this.strategy = strategy;
  }

  @Override
  public Rule toRule(){
      AuthorityRule rule=new AuthorityRule();
      return rule;
  }

}
@Bean
public Converter<java.util.List<AuthorityRuleCorrectEntity>, String> authorityRuleCorrectEntityEncoder() {
    return JSON::toJSONString;
}
 
@Bean
public Converter<String, java.util.List<AuthorityRuleCorrectEntity>> authorityRuleCorrectEntityDecoder() {
    return s -> JSON.parseArray(s, AuthorityRuleCorrectEntity.class);
}

1.2.3.4 步和热点一样

总结:

sentinel 在往nacos推送时候转换成客户端想要的格式。在控制台返回时候将其自定义的类转换成sentinel想要的格式。就完事了
谢谢大家 ~~~~

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
### 回答1: b'sentinel规则持久化nacos'的意思是将Sentinel规则持久化Nacos中,使得在规则发生变化时,可以自动同步至Nacos中,保证系统的稳定性和可靠性。这样做也便于管理和维护规则信息。 ### 回答2: Sentinel规则持久化是指将在Sentinel配置规则信息保存到外部存储器中,以便于在应用启动时,可以从外部存储器中加载规则,从而实现规则的自动化配置Nacos是一款开源的动态服务发现、配置管理和服务管理平台。它可以用于管理应用程序的配置信息、服务发现和服务注册。Sentinel是阿里巴巴开源的一款微服务框架。它可以用于在分布式系统中实现流量控制、熔断降级和系统负载保护等功能。 在分布式环境中,由于存在多个节点,这些节点之间需要共享配置信息和规则信息。传统的配置规则信息的管理方式比较繁琐,需要手动配置,而且容易出现人为错误。因此,将规则信息持久化Nacos中,可以实现自动化配置和管理,从而提高规则信息的管理效率和运维效率。 具体来说,Sentinel可以通过配置文件的方式将规则信息持久化Nacos中。首先需要在Nacos中创建一个配置集群,然后在Sentinel进行配置,指定配置的数据源为Nacos。这样就可以将Sentinel中的规则信息保存到Nacos中。 在系统运行时,Sentinel可以从Nacos中加载规则信息,并根据规则信息对流量进行控制。如果规则信息发生变化,Sentinel也可以及时地更新规则信息。因此,利用Nacos持久化规则信息,可以实现规则动态管理和自动化配置,提高系统的稳定性和可靠性。 总之,Sentinel规则持久化Nacos中,可以实现规则的自动化管理和动态配置。它具有管理效率高、运维效率高、稳定性好等优点。因此,在分布式环境中,将规则信息持久化Nacos中,是一种非常值得推广的做法。 ### 回答3: Sentinel规则持久化Nacos是为了让Sentinel控制台中配置规则在重启后仍能够保留,避免重启后规则丢失需要重新手动配置问题Nacos是一个开源的注册中心和配置中心,支持分布式场景下的服务注册、配置管理和服务发现。在Sentinel中,我们可以通过将规则持久化Nacos中来实现持久化的功能。 首先,我们需要在控制台中配置Nacos的相关信息,包括Nacos Server地址、Data ID和Group信息等。其中,Data ID和Group信息用于标识Sentinel规则的唯一性。 接下来,我们需要通过编写代码来实现将Sentinel规则持久化Nacos中。具体实现方式可以参考官方文档中提供的示例代码,主要包括以下几个步骤: 1. 创建Nacos配置管理客户端,可以通过NacosFactory.createConfigService()方法获取。 2. 将Sentinel规则序列化成JSON字符串,可以通过Jackson等工具实现。 3. 调用Nacos的API,将JSON字符串保存到Nacos中,例如使用configService.publishConfig()方法。 4. 在Sentinel应用启动时,需要从Nacos读取保存的规则信息,并将其解析成Sentinel规则对象,例如使用configService.getConfig()方法获取Nacos中的配置信息,之后再调用SentinelRuleParser.parseRules()方法将其转换为Sentinel规则对象。 5. 在控制台中修改或删除规则时,需要通过调用Nacos的API来更新或删除相应的配置信息,例如使用configService.publishConfig()和cconfigService.removeConfig()方法实现。 通过以上步骤,我们就可以实现将Sentinel规则持久化Nacos中的功能,保证了应用重启后规则仍能够得到保留。同时,使用Nacos作为规则持久化的中心,还能够实现多节点之间的规则同步和分布式配置的管理。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值