改造sentinel控制台测试推模式时候,热点规则的问题。
2020-09-23 本文已影响0人
Gason_d796
问题:
- 控制台推送热点规则和授权规则时,客户端规则不生效。
原因:
- 通过断点发现 dashboard中ParamFlowRuleEntity推送上去后,结构和ParamFlowRule不一样,导致客户端拉取后无法转成ParamFlowRule故无法生效(AuthorityRule也一样)
修复:
- 重写ParamFlowRuleEntity-》ParamFlowRuleCorrectEntity
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;
}
}
- 单独写Converter的转换方法
publisher
@Component("paramFlowRuleZookeeperPublisher")
public class ParamFlowRuleZookeeperPublisher extends RuleZkPublisher<ParamFlowRuleEntity> {
@Value("${sentinel.param.prex}")
private String type;
@Override
public String getDataIdPostfix() {
return type;
}
@Autowired
private Converter<List<ParamFlowRuleCorrectEntity>, String> converterParam;
@Override
public void publish(String app, List<ParamFlowRuleEntity> rules) throws Exception {
// 转换
List<ParamFlowRuleCorrectEntity> list = rules.stream().map(rule -> {
ParamFlowRuleCorrectEntity entity = new ParamFlowRuleCorrectEntity();
BeanUtils.copyProperties(rule,entity);
return entity;
}).collect(Collectors.toList());
AssertUtil.notEmpty(app, "app name cannot be empty");
String path = ZookeeperConfigUtil.getPath(app, getDataIdPostfix());
Stat stat = zkClient.checkExists().forPath(path);
if (stat == null) {
zkClient.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, null);
}
byte[] data = CollectionUtils.isEmpty(rules) ? "[]".getBytes() : converterParam.convert(list).getBytes();
zkClient.setData().forPath(path, data);
}
}
provider
@Component("paramFlowRuleZookeeperProvider")
public class ParamFlowRuleZookeeperProvider extends RuleZkProvider<ParamFlowRuleEntity> {
@Value("${sentinel.param.prex}")
private String type;
@Override
public String getDataIdPostfix() {
return type;
}
@Autowired
private Converter<String, List<ParamFlowRuleCorrectEntity>> converterParam;
@Override
public List<ParamFlowRuleEntity> getRules(String appName) throws Exception {
String zkPath = ZookeeperConfigUtil.getPath(appName, getDataIdPostfix());
Stat stat = zkClient.checkExists().forPath(zkPath);
if (stat == null) {
return new ArrayList<>(0);
}
byte[] bytes = zkClient.getData().forPath(zkPath);
if (null == bytes || bytes.length == 0) {
return new ArrayList<>();
}
String s = new String(bytes);
List<ParamFlowRuleCorrectEntity> list = converterParam.convert(s);
//转换
return list.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());
}
}
工程代码: https://github.com/Gasonzhong/sentinel-zookeeper-dashboard