关于Alibaba Sentinel dashboard对数据进行持久化保存到数据源中,热点规则及授权规则和单机模式无法兼容的问题的解决方案

在改造Sentinel sashboard实现和数据源持久化的过程中,遇到了热点规则及授权规则和单机模式无法兼容的问题,就是你改变了集群的热点规则及授权规则后,虽然持久化到数据源中,但是单机模式无法解析规则。使得规则无法打通。

究其原因,就是集群V2模式保存的数据,多了一级rule。所以保存和读取的时候就要稍微调整一下。

单机的loadConfig解析
[{"burstCount":0,"clusterConfig":{"fallbackToLocalWhenFail":true,"sampleCount":10,"thresholdType":0,"windowIntervalMs":1000},"clusterMode":false,"controlBehavior":0,"count":8888.0,"durationInSec":8888,"grade":1,"limitApp":"default","maxQueueingTimeMs":0,"paramFlowItemList":[],"paramIdx":8888,"resource":"66666"}]

V2的loadConfig解析
[{"app":"i5xforyou","gmtCreate":1594287624052,"gmtModified":1594289440542,"id":38,"ip":"192.168.14.187","port":8720,"rule":{"burstCount":0,"clusterConfig":{"fallbackToLocalWhenFail":true,"sampleCount":10,"thresholdType":0,"windowIntervalMs":1000},"clusterMode":false,"controlBehavior":0,"count":111.0,"durationInSec":1111112,"grade":1,"limitApp":"default","maxQueueingTimeMs":0,"paramFlowItemList":[],"paramIdx":22222222,"resource":"SSSS"}}]

原理不过多在解释了,解决方法如下,

以Publisher方法为例,增加如下方法

    private String parseRules(String rules) {
        JSONArray oldRuleJsons = JSONArray.parseArray(rules);
        for (int i = 0; i < oldRuleJsons.size(); i++) {
        	JSONObject oldRuleJson = oldRuleJsons.getJSONObject(i);
        	JSONObject ruleJson = oldRuleJson.getJSONObject("rule");
        	oldRuleJson.putAll(ruleJson);
        	oldRuleJson.remove("rule");
		}
        return oldRuleJsons.toJSONString();
    }


 byte[] data = CollectionUtils.isEmpty(rules) ? "[]".getBytes() : converter.convert(rules).getBytes();

变为

 byte[] data = CollectionUtils.isEmpty(rules) ? "[]".getBytes() : this.parseRules(converter.convert(rules)).getBytes();

provider方法则有些不同

授权规则需要添加如下方法:

 private String parseRules(String rules) {
    	JSONArray newRuleJsons = new JSONArray();
        JSONArray ruleJsons = JSONArray.parseArray(rules);
        for (int i = 0; i < ruleJsons.size(); i++) {       	
        	JSONObject ruleJson = ruleJsons.getJSONObject(i);
        	AuthorityRuleEntity ruleEntity = JSON.parseObject(ruleJson.toJSONString(), AuthorityRuleEntity.class);
        	JSONObject newRuleJson = JSON.parseObject(JSON.toJSONString(ruleEntity));
        	AuthorityRule rule = JSON.parseObject(ruleJson.toJSONString(), AuthorityRule.class);
        	newRuleJson.put("rule", rule);
        	newRuleJsons.add(newRuleJson);
		}
        return newRuleJsons.toJSONString();
    }

热点规则需要添加如下方法:

    private String parseRules(String rules) {
    	JSONArray newRuleJsons = new JSONArray();
        JSONArray ruleJsons = JSONArray.parseArray(rules);
        for (int i = 0; i < ruleJsons.size(); i++) {       	
        	JSONObject ruleJson = ruleJsons.getJSONObject(i);
        	ParamFlowRuleEntity ruleEntity = JSON.parseObject(ruleJson.toJSONString(), ParamFlowRuleEntity.class);
        	JSONObject newRuleJson = JSON.parseObject(JSON.toJSONString(ruleEntity));
        	ParamFlowRule rule = JSON.parseObject(ruleJson.toJSONString(), ParamFlowRule.class);
        	newRuleJson.put("rule", rule);
        	newRuleJsons.add(newRuleJson);
		}
        return newRuleJsons.toJSONString();
    }

getRules方法下的

return converter.convert(s); 调整为 return converter.convert(this.parseRules(s));

问题解决。

 

更多关于 sentinel dashboard 持久化改造 zookeeper nacos的源码,https://gitee.com/ankeway/Sentinel.git  master-dashboard分支查看

你可能感兴趣的:(SpringCloud)