sentinel改造Nacos动态规则热点规则和授权规则不生效的问题
Sentinel
alibaba/Sentinel: Sentinel 是阿里巴巴开源的一款面向分布式服务架构的流量控制、熔断降级组件,提供实时监控、限流、降级和系统保护功能,适用于微服务治理场景。
项目地址:https://gitcode.com/gh_mirrors/sentine/Sentinel
免费下载资源
·
问题原因:
通过断点发现 dashboard中ParamFlowRuleEntity推送上去后,结构和ParamFlowRule不一样,导致客户端拉取后无法转成ParamFlowRule故无法生效(AuthorityRule也一样),主要原因就是转换过后客户端获取规则时,无法从规则中找到resouce,导致规则校验时根据资源名称去获取规则信息无法获取到规则,进而导致规则不生效的问题
解决方案:
重写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 chengmeng
* @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<java.util.List<ParamFlowRuleCorrectEntity>, String> paramFlowRuleCorrectEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, java.util.List<ParamFlowRuleCorrectEntity>> paramFlowRuleCorrectEntityDecoder() {
return s -> JSON.parseArray(s, ParamFlowRuleCorrectEntity.class);
}
第三步:修改对应的NacosProvider
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.NacosConfig;
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 java.util.ArrayList;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author chengmeng
* @description
* @date 2021/2/4 10:04
*/
@Component("paramFlowRuleNacosProvider")
public class ParamFlowRuleNacosProvider implements DynamicRuleProvider<java.util.List<ParamFlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private NacosConfig nacosConfig;
@Autowired
private Converter<String, java.util.List<ParamFlowRuleCorrectEntity>> converter;
@Override
public java.util.List<ParamFlowRuleEntity> getRules(String appName) throws Exception {
final String group = StringUtils.isNotEmpty(nacosConfig.getGroup()) ?
nacosConfig.getGroup() :
NacosConfigUtil.GROUP_ID;
String rules = configService.getConfig(appName + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
group, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
java.util.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.fromAuthorityRule(rule.getApp(), rule.getIp(), rule.getPort(), paramFlowRule);
entity.setId(rule.getId());
entity.setGmtCreate(rule.getGmtCreate());
return entity;
}).collect(Collectors.toList());
}
}
第四步:修改对应的NacosPublisher
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.NacosConfig;
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.apache.commons.lang3.StringUtils;
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 chengmeng
* @description
* @date 2021/2/4 10:04
*/
@Component("paramFlowRuleNacosPublisher")
public class ParamFlowRuleNacosPublisher implements DynamicRulePublisher<java.util.List<ParamFlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private NacosConfig nacosConfig;
@Autowired
private Converter<java.util.List<ParamFlowRuleCorrectEntity>, String> converter;
@Override
public void publish(String app, java.util.List<ParamFlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
for (ParamFlowRuleEntity rule : rules) {
if (rule.getApp() == null) {
rule.setApp(app);
}
}
// 转换
List<ParamFlowRuleCorrectEntity> list = rules.stream().map(rule -> {
ParamFlowRuleCorrectEntity entity = new ParamFlowRuleCorrectEntity();
BeanUtils.copyProperties(rule,entity);
return entity;
}).collect(Collectors.toList());
final String group = StringUtils.isNotEmpty(nacosConfig.getGroup()) ?
nacosConfig.getGroup() :
NacosConfigUtil.GROUP_ID;
configService.publishConfig(app + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
group, 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;
}
}
第二步:在NacosConfig添加对应的类型转换配置
@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);
}
第三步:修改对应的NacosProvider
package com.alibaba.csp.sentinel.dashboard.rule.nacos.authority;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleCorrectEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
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.NacosConfig;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
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 java.util.ArrayList;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author chengmeng
* @description
* @date 2021/2/4 14:08
*/
@Component("authorityRuleNacosProvider")
public class AuthorityRuleNacosProvider implements DynamicRuleProvider<java.util.List<AuthorityRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private NacosConfig nacosConfig;
@Autowired
private Converter<String, java.util.List<AuthorityRuleCorrectEntity>> converter;
@Override
public java.util.List<AuthorityRuleEntity> getRules(String appName) throws Exception {
final String group = StringUtils.isNotEmpty(nacosConfig.getGroup()) ?
nacosConfig.getGroup() :
NacosConfigUtil.GROUP_ID;
String rules = configService.getConfig(appName + NacosConfigUtil.AUTHORITY_DATA_ID_POSTFIX, group, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
java.util.List<AuthorityRuleCorrectEntity> entityList = converter.convert(rules);
entityList.forEach(e -> e.setApp(appName));
return entityList.stream().map(rule -> {
AuthorityRule authorityRule = new AuthorityRule();
BeanUtils.copyProperties(rule, authorityRule);
AuthorityRuleEntity entity = AuthorityRuleEntity.fromAuthorityRule(rule.getApp(), rule.getIp(), rule.getPort(), authorityRule);
entity.setId(rule.getId());
entity.setGmtCreate(rule.getGmtCreate());
return entity;
}).collect(Collectors.toList());
}
}
第四步:修改对应的NacosPublisher
package com.alibaba.csp.sentinel.dashboard.rule.nacos.authority;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleCorrectEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleCorrectEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfig;
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.apache.commons.lang3.StringUtils;
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 chengmeng
* @description
* @date 2021/2/4 14:08
*/
@Component("authorityRuleNacosPublisher")
public class AuthorityRuleNacosPublisher implements DynamicRulePublisher<java.util.List<AuthorityRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private NacosConfig nacosConfig;
@Autowired
private Converter<java.util.List<AuthorityRuleCorrectEntity>, String> converter;
@Override
public void publish(String app, java.util.List<AuthorityRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
final String group = StringUtils.isNotEmpty(nacosConfig.getGroup()) ?
nacosConfig.getGroup() :
NacosConfigUtil.GROUP_ID;
if (rules == null) {
return;
}
for (AuthorityRuleEntity rule : rules) {
if (rule.getApp() == null) {
rule.setApp(app);
}
}
// 转换
List<AuthorityRuleCorrectEntity> list = rules.stream().map(rule -> {
AuthorityRuleCorrectEntity entity = new AuthorityRuleCorrectEntity();
BeanUtils.copyProperties(rule,entity);
return entity;
}).collect(Collectors.toList());
configService.publishConfig(app + NacosConfigUtil.AUTHORITY_DATA_ID_POSTFIX,
group, converter.convert(list));
}
}
以上就是对热点参数规则以及授权规则的修改已经完成。
GitHub 加速计划 / sentine / Sentinel
22.24 K
7.98 K
下载
alibaba/Sentinel: Sentinel 是阿里巴巴开源的一款面向分布式服务架构的流量控制、熔断降级组件,提供实时监控、限流、降级和系统保护功能,适用于微服务治理场景。
最近提交(Master分支:3 个月前 )
195150bc
* fix issue 2485 which occur oom when using async servlet request.
* optimize imports
* 1. fix the same issue in the webmvc-v6x
2. improve based on review comments 2 个月前
b78b09d3
2 个月前
更多推荐
已为社区贡献4条内容
所有评论(0)