由于甲方领导要求,将spring版本升级至5.2.9及以上版本,目前升级至5.3.3
连带升级为:
springboot 2.3.0.RELEASE -> 2.4.2
springcloud 2.2.3.RELEASE -> 2020.0.3
springcloudAlibaba 2.2.1.RELEASE ->2021.1
sentinel 1.7.2 ->1.8.1
本次记录为:
项目升级spring-core并升级框架后,原始代码出现不兼容或Sentinel 出现的bug,导致使用
GatewayRuleManager.loadRules(rules)
对流控规则进行更新时,出现空指针的情况
GatewayRuleManager源码第217-244行:
if (newRuleMap != null && !newRuleMap.isEmpty()) {
var3 = GatewayRuleManager.CONVERTED_PARAM_RULE_MAP.entrySet().iterator();//218
while(true) {
while(var3.hasNext()) {//221
Entry<String, List<ParamFlowRule>> entry = (Entry)var3.next();
String resource = (String)entry.getKey();
if (!newRuleMap.containsKey(resource)) {
ParameterMetricStorage.clearParamMetricForResource(resource);
} else {
List<ParamFlowRule> newRuleList = (List)newRuleMap.get(resource);
List<ParamFlowRule> oldRuleList = new ArrayList((Collection)entry.getValue());
oldRuleList.removeAll(newRuleList);
Iterator var8 = oldRuleList.iterator();//230行
while(var8.hasNext()) {
ParamFlowRule rule = (ParamFlowRule)var8.next();
ParameterMetricStorage.getParamMetricForResource(resource).clearForRule(rule);
}
}
}
GatewayRuleManager.CONVERTED_PARAM_RULE_MAP.clear();//239
GatewayRuleManager.CONVERTED_PARAM_RULE_MAP.putAll(newRuleMap);//240
RecordLog.info("[GatewayRuleManager] Converted internal param rules: " + GatewayRuleManager.CONVERTED_PARAM_RULE_MAP, new Object[0]);
return;
}
}
230行出现空指针.
由于时间关系,并未能对bug进行分析,初步判断为"更新框架后,可能某个框架重写了类的toString()导致某些识别出现了问题"
但GatewayRuleManager源码239.240行源码为:
GatewayRuleManager.CONVERTED_PARAM_RULE_MAP.clear();
GatewayRuleManager.CONVERTED_PARAM_RULE_MAP.putAll(newRuleMap);
GatewayRuleManager最终似乎会将RULE_MAP清空,并putAll新的规则.
因此本次项目中代码修改为:
GatewayRuleManager.loadRules(new HashSet()<>);
GatewayRuleManager.loadRules(rules);
在更新规则前,清空规则,以此跳过221行
while(var3.hasNext()) {
的判断,直接进入239,240
本次修改并不保证功能完全正常,仅为修改记录