1.Sentinel源码分析—FlowRuleManager加载规则做了什么? (5)

我们进入到DynamicSentinelProperty的updateValue中:

public boolean updateValue(T newValue) { //判断新的元素和旧元素是否相同 if (isEqual(value, newValue)) { return false; } RecordLog.info("[DynamicSentinelProperty] Config will be updated to: " + newValue); value = newValue; for (PropertyListener<T> listener : listeners) { listener.configUpdate(newValue); } return true; }

updateValue方法就是校验一下是不是已经存在相同的规则了,如果不存在那么就直接设置value等于新的规则,然后通知所有的监听器更新一下规则配置。

currentProperty实例里面的监听器会在FlowRuleManager初始化静态代码块的时候设置一个FlowPropertyListener监听器实例,FlowPropertyListener是FlowRuleManager的内部类:

private static final class FlowPropertyListener implements PropertyListener<List<FlowRule>> { @Override public void configUpdate(List<FlowRule> value) { Map<String, List<FlowRule>> rules = FlowRuleUtil.buildFlowRuleMap(value); if (rules != null) { flowRules.clear(); //这个map的维度是key是Resource flowRules.putAll(rules); } RecordLog.info("[FlowRuleManager] Flow rules received: " + flowRules); } .... }

configUpdate首先会调用FlowRuleUtil.buildFlowRuleMap()方法将所有的规则按resource分类,然后排序返回成map,然后将FlowRuleManager的原来的规则清空,放入新的规则集合到flowRules中去。

FlowRuleUtil#buildFlowRuleMap
这个方法最后会调用到FlowRuleUtil的另一个重载的方法:

public static <K> Map<K, List<FlowRule>> buildFlowRuleMap(List<FlowRule> list, Function<FlowRule, K> groupFunction, Predicate<FlowRule> filter, boolean shouldSort) { Map<K, List<FlowRule>> newRuleMap = new ConcurrentHashMap<>(); if (list == null || list.isEmpty()) { return newRuleMap; } Map<K, Set<FlowRule>> tmpMap = new ConcurrentHashMap<>(); for (FlowRule rule : list) { //校验必要字段:资源名,限流阈值, 限流阈值类型,调用关系限流策略,流量控制效果等 if (!isValidRule(rule)) { RecordLog.warn("[FlowRuleManager] Ignoring invalid flow rule when loading new flow rules: " + rule); continue; } if (filter != null && !filter.test(rule)) { continue; } //应用名,如果没有则会使用default if (StringUtil.isBlank(rule.getLimitApp())) { rule.setLimitApp(RuleConstant.LIMIT_APP_DEFAULT); } //设置拒绝策略:直接拒绝、Warm Up、匀速排队,默认是DefaultController TrafficShapingController rater = generateRater(rule); rule.setRater(rater); //获取Resource名字 K key = groupFunction.apply(rule); if (key == null) { continue; } //根据Resource进行分组 Set<FlowRule> flowRules = tmpMap.get(key); if (flowRules == null) { // Use hash set here to remove duplicate rules. flowRules = new HashSet<>(); tmpMap.put(key, flowRules); } flowRules.add(rule); } //根据ClusterMode LimitApp排序 Comparator<FlowRule> comparator = new FlowRuleComparator(); for (Entry<K, Set<FlowRule>> entries : tmpMap.entrySet()) { List<FlowRule> rules = new ArrayList<>(entries.getValue()); if (shouldSort) { // Sort the rules. Collections.sort(rules, comparator); } newRuleMap.put(entries.getKey(), rules); } return newRuleMap; }

这个方法首先校验传进来的rule集合不为空,然后遍历rule集合。对rule的必要字段进行校验,如果传入了过滤器那么校验过滤器,然后过滤resource为空的rule,最后相同的resource的rule都放到一起排序后返回。
注意这里默认生成的rater是DefaultController。

到这里FlowRuleManager已经分析完毕了,比较长。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzwzz.html