博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dubbo源码解析(三十六)集群——configurator
阅读量:7065 次
发布时间:2019-06-28

本文共 5970 字,大约阅读时间需要 19 分钟。

集群——configurator

目标:介绍dubbo中集群的配置规则,介绍dubbo-cluster下configurator包的源码。

前言

向注册中心写入动态配置覆盖规则 。该功能通常由监控中心或治理中心的页面完成。在最新的2.7.0版本中有新的配置规则,我会在后续讲解2.7.0新特性的时候提到。这里还是根据旧版本中配置规则来讲解,可以参考官方文档:

源码分析

(一)AbstractConfigurator

该类实现了Configurator接口,是配置规则 抽象类,配置有两种方式,一种是没有时添加配置,这种暂时没有用到,另一种是覆盖配置。

1.configure

@Overridepublic URL configure(URL url) {    if (configuratorUrl == null || configuratorUrl.getHost() == null            || url == null || url.getHost() == null) {        return url;    }    // If override url has port, means it is a provider address. We want to control a specific provider with this override url, it may take effect on the specific provider instance or on consumers holding this provider instance.    // 如果覆盖url具有端口,则表示它是提供者地址。我们希望使用此覆盖URL控制特定提供程序,它可以在提供端生效 也可以在消费端生效。    if (configuratorUrl.getPort() != 0) {        if (url.getPort() == configuratorUrl.getPort()) {            return configureIfMatch(url.getHost(), url);        }    } else {// override url don't have a port, means the ip override url specify is a consumer address or 0.0.0.0        // 1.If it is a consumer ip address, the intention is to control a specific consumer instance, it must takes effect at the consumer side, any provider received this override url should ignore;        // 2.If the ip is 0.0.0.0, this override url can be used on consumer, and also can be used on provider        // 配置规则,URL 没有端口,意味着override 输入消费端地址 或者 0.0.0.0        if (url.getParameter(Constants.SIDE_KEY, Constants.PROVIDER).equals(Constants.CONSUMER)) {            // 如果它是一个消费者ip地址,目的是控制一个特定的消费者实例,它必须在消费者一方生效,任何提供者收到这个覆盖url应该忽略;            return configureIfMatch(NetUtils.getLocalHost(), url);// NetUtils.getLocalHost is the ip address consumer registered to registry.        } else if (url.getParameter(Constants.SIDE_KEY, Constants.CONSUMER).equals(Constants.PROVIDER)) {            // 如果ip为0.0.0.0,则此覆盖url可以在使用者上使用,也可以在提供者上使用            return configureIfMatch(Constants.ANYHOST_VALUE, url);// take effect on all providers, so address must be 0.0.0.0, otherwise it won't flow to this if branch        }    }    return url;}

该方法是规则配置到URL中,但是关键逻辑在configureIfMatch方法中。

2.configureIfMatch

private URL configureIfMatch(String host, URL url) {    // 匹配 Host    if (Constants.ANYHOST_VALUE.equals(configuratorUrl.getHost()) || host.equals(configuratorUrl.getHost())) {        String configApplication = configuratorUrl.getParameter(Constants.APPLICATION_KEY,                configuratorUrl.getUsername());        String currentApplication = url.getParameter(Constants.APPLICATION_KEY, url.getUsername());        // 匹配 "application"        if (configApplication == null || Constants.ANY_VALUE.equals(configApplication)                || configApplication.equals(currentApplication)) {            Set
conditionKeys = new HashSet
(); // 配置 URL 中的条件 KEYS 集合。其中下面四个 KEY ,不算是条件,而是内置属性。考虑到下面要移除,所以添加到该集合中。 conditionKeys.add(Constants.CATEGORY_KEY); conditionKeys.add(Constants.CHECK_KEY); conditionKeys.add(Constants.DYNAMIC_KEY); conditionKeys.add(Constants.ENABLED_KEY); // 判断传入的 url 是否匹配配置规则 URL 的条件。 for (Map.Entry
entry : configuratorUrl.getParameters().entrySet()) { String key = entry.getKey(); String value = entry.getValue(); // 除了 "application" 和 "side" 之外,带有 `"~"` 开头的 KEY ,也是条件。 if (key.startsWith("~") || Constants.APPLICATION_KEY.equals(key) || Constants.SIDE_KEY.equals(key)) { // 添加搭配条件集合 conditionKeys.add(key); if (value != null && !Constants.ANY_VALUE.equals(value) && !value.equals(url.getParameter(key.startsWith("~") ? key.substring(1) : key))) { return url; } } } // 移除条件 KEYS 集合,并配置到 URL 中 return doConfigure(url, configuratorUrl.removeParameters(conditionKeys)); } } return url;}

该方法是当条件匹配时,才对url进行配置。

3.compareTo

@Overridepublic int compareTo(Configurator o) {    if (o == null) {        return -1;    }    // // host 升序    int ipCompare = getUrl().getHost().compareTo(o.getUrl().getHost());    // 如果host相同,则根据priority降序来对比    if (ipCompare == 0) {//host is the same, sort by priority        int i = getUrl().getParameter(Constants.PRIORITY_KEY, 0),                j = o.getUrl().getParameter(Constants.PRIORITY_KEY, 0);        return i < j ? -1 : (i == j ? 0 : 1);    } else {        return ipCompare;    }}

这是配置的排序策略。先根据host升序,如果相同,再通过priority降序。

(二)AbsentConfigurator

public class AbsentConfigurator extends AbstractConfigurator {    public AbsentConfigurator(URL url) {        super(url);    }    @Override    public URL doConfigure(URL currentUrl, URL configUrl) {        // 当不存在时添加        return currentUrl.addParametersIfAbsent(configUrl.getParameters());    }}

该配置方式就是当配置不存在的时候添加。

(三)AbsentConfiguratorFactory

public class AbsentConfiguratorFactory implements ConfiguratorFactory {    @Override    public Configurator getConfigurator(URL url) {        // 创建一个AbsentConfigurator。        return new AbsentConfigurator(url);    }}

该类是不存在时添加配置的工厂类,用来创建AbsentConfigurator。

(四)OverrideConfigurator

public class OverrideConfigurator extends AbstractConfigurator {    public OverrideConfigurator(URL url) {        super(url);    }    @Override    public URL doConfigure(URL currentUrl, URL configUrl) {        // 覆盖添加        return currentUrl.addParameters(configUrl.getParameters());    }}

这种是覆盖添加。是目前在用的配置方式。

(五)OverrideConfiguratorFactory

public class OverrideConfiguratorFactory implements ConfiguratorFactory {    @Override    public Configurator getConfigurator(URL url) {        // 创建OverrideConfigurator        return new OverrideConfigurator(url);    }}

该类是OverrideConfigurator的工厂类,用来提供OverrideConfigurator实例。

后记

该部分相关的源码解析地址:

该文章讲解了集群中关于configurator实现的部分,讲了两种配置方式,分别是不存在再添加和覆盖添加。接下来我将开始对集群模块关于Directory部分进行讲解。

转载地址:http://cfill.baihongyu.com/

你可能感兴趣的文章
TypeScript 学习笔记
查看>>
Selenium3+python3-发送添加附件的邮件
查看>>
移动端-必要知识
查看>>
Redis指令
查看>>
Date12
查看>>
HTTP协议09-响应首部字段
查看>>
【原创】MySQL新旧版本ORDER BY 处理方法
查看>>
Cocos2d-x Eclipse下程序运行产生错误Effect initCheck() returned -1
查看>>
linux shell单引号、双引号及无引号区别(考试题答案系列)
查看>>
625某电商网站数据库宕机故障解决实录(下)
查看>>
创业公司感悟录之十个提醒—作者李天平
查看>>
.NET Project Open Day(2011.11.13)
查看>>
centos 记录用户行为轨迹
查看>>
各角色眼中的性能测试
查看>>
Citrix XenDesktop 引发的学案(四)-与“您的虚拟桌面”之间的连接失败,状态(1030)...
查看>>
mysql-5.6的GTID复制的实现
查看>>
6421B Lab10 网络文件和打印服务的配置与故障排除
查看>>
快速安装配置zabbix_agent端
查看>>
DNS服务的配置与管理(5) 配置转发器
查看>>
AIP(Azure 信息保护)之一:启用与激活服务
查看>>