Dubbo动态配置override协议(八)
override协议可以让用户动态修改配置,并实时生效。关于动态配置的介绍可以详细看官网https://dubbo.apache.org/zh/docs/v2.7/user/examples/config-rule-deprecated/#m-zhdocsv27userexamplesconfig-rule-deprecated
当在dubbo-admin(管理后台)中创建一条override规则后,会首先存储在注册中心(zookeeper的指定目录下${service}/configurators目录下,此时基于注册中心的事件机制,会通知相关监听者(服务消费者),服务消费者收到最新的配置时,会根据最新的配置重新构建Invoker对象,然后销毁原先的Invoker对象。
接下来我们再来看一下RegistryDirectory#notify方法。
@Override public synchronized void notify(List<URL> urls) { Map<String, List<URL>> categoryUrls = urls.stream() .filter(Objects::nonNull) .filter(this::isValidCategory) .filter(this::isNotCompatibleFor26x) .collect(Collectors.groupingBy(url -> { if (UrlUtils.isConfigurator(url)) { // override协议开头 return CONFIGURATORS_CATEGORY; } else if (UrlUtils.isRoute(url)) { return ROUTERS_CATEGORY; } else if (UrlUtils.isProvider(url)) { return PROVIDERS_CATEGORY; } return ""; })); List<URL> configuratorURLs = categoryUrls.getOrDefault(CONFIGURATORS_CATEGORY, Collections.emptyList()); // 将configuratorUrls转换为配置对象List< Configurator> configurators this.configurators = Configurator.toConfigurators(configuratorURLs).orElse(this.configurators); List<URL> routerURLs = categoryUrls.getOrDefault(ROUTERS_CATEGORY, Collections.emptyList()); // 将routerUrls路由URL转换为Router对象 toRouters(routerURLs).ifPresent(this::addRouters); // providers List<URL> providerURLs = categoryUrls.getOrDefault(PROVIDERS_CATEGORY, Collections.emptyList()); refreshOverrideAndInvoker(providerURLs); }
最后一行代码overrideDirectoryUrl();先把所有的服务提供者的URL刷到overrideDirectoryUrl,其中就涉及到对URL做进一步处理后,比如排除不能动态修改的属性,不支持属性主要包括:category、check、dynamic、enabled、还有以开头的属性,并且如果开头的属性,配置URL与原URL的值不相同,则不使用该配置URL重写原URL。将配置URL(configuratorUrl)移除不支持属性后,调用其子类的doConfigure方法覆盖属性,Dubbo默认支持override和absent策略。
refreshInvoker(urls)最后根据urls来创建新的invoker,替换原来的invoker,销毁没有用的invoker。