dubbo下Dubbo协议注册中心理解getRegistry方法理解注释

RegistryProtocol export 暴露服务为例
public void register(URL registryUrl, URL registedProviderUrl) {
    Registry registry = registryFactory.getRegistry(registryUrl);
    registry.register(registedProviderUrl);
}

public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
    //export invoker
    final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
    //转换为指定注册协议
    URL registryUrl = getRegistryUrl(originInvoker);
    //registry provider 获取注册中心 这里主要解释这个方法
    final Registry registry = getRegistry(originInvoker);
    final URL registedProviderUrl = getRegistedProviderUrl(originInvoker);
    //to judge to delay publish whether or not
    boolean register = registedProviderUrl.getParameter("register", true);
    ProviderConsumerRegTable.registerProvider(originInvoker, registryUrl, registedProviderUrl);
    if (register) {
        register(registryUrl, registedProviderUrl);
        ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
    }

    // Subscribe the override data
    // FIXME When the provider subscribes, it will affect the scene : a certain JVM exposes the service and call the same service. Because the subscribed is cached key with the name of the service, it causes the subscription information to cover.
    final URL overrideSubscribeUrl = getSubscribedOverrideUrl(registedProviderUrl);
    final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
    overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
    registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
    //Ensure that a new exporter instance is returned every time export
    return new DestroyableExporter<T>(exporter, originInvoker, overrideSubscribeUrl, registedProviderUrl);
}
 
AbstractRegistryFactory
@Override
public Registry getRegistry(URL url) {
    url = url.setPath(RegistryService.class.getName())
            .addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName())
            .removeParameters(Constants.EXPORT_KEY, Constants.REFER_KEY);
    String key = url.toServiceString();
    // Lock the registry access process to ensure a single instance of the registry
    LOCK.lock();
    try {
        Registry registry = REGISTRIES.get(key);
        if (registry != null) {
            return registry;
        }
        registry = createRegistry(url); 创建注册中心实例并返回
        if (registry == null) {
            throw new IllegalStateException("Can not create registry " + url);
        }
        REGISTRIES.put(key, registry);
        return registry;
    } finally {
        // Release the lock
        LOCK.unlock();
    }
}
 
DubboRegistryFactory
@Override
public Registry createRegistry(URL url) {
    url = getRegistryURL(url); 转换为对应协议及过滤的url
    List<URL> urls = new ArrayList<URL>();
    urls.add(url.removeParameter(Constants.BACKUP_KEY));
    String backup = url.getParameter(Constants.BACKUP_KEY);backup 为集群备用注册
    if (backup != null && backup.length() > 0) {
        String[] addresses = Constants.COMMA_SPLIT_PATTERN.split(backup);
        for (String address : addresses) {
            urls.add(url.setAddress(address));
        }
    }
    RegistryDirectory<RegistryService> directory = new RegistryDirectory<RegistryService>(RegistryService.class, url.addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName()).addParameterAndEncoded(Constants.REFER_KEY, url.toParameterString()));
    Invoker<RegistryService> registryInvoker = cluster.join(directory);
    Directory代表多个Invoker,可以把它看成List,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更。Cluster将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个。
    RegistryService registryService = proxyFactory.getProxy(registryInvoker);
    DubboRegistry registry = new DubboRegistry(registryInvoker, registryService);
    directory.setRegistry(registry);
    directory.setProtocol(protocol);
    directory.notify(urls);
    directory.subscribe(new URL(Constants.CONSUMER_PROTOCOL, NetUtils.getLocalHost(), 0, RegistryService.class.getName(), url.getParameters()));
    return registry;
}
RegistryDirectory
public void subscribe(URL url) {
    setConsumerUrl(url);
    registry.subscribe(url, this);
}

 
FailbackRegistry
@Override
public void subscribe(URL url, NotifyListener listener) {
    super.subscribe(url, listener);
    removeFailedSubscribed(url, listener);
    try {
        // Sending a subscription request to the server side
        doSubscribe(url, listener); 这里使用了抽象方法由子类来实现
    } catch (Exception e) {
        Throwable t = e;

        List<URL> urls = getCacheUrls(url);
        if (urls != null && !urls.isEmpty()) {
            notify(url, listener, urls);
            logger.error("Failed to subscribe " + url + ", Using cached list: " + urls + " from cache file: " + getUrl().getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/dubbo-registry-" + url.getHost() + ".cache") + ", cause: " + t.getMessage(), t);
        } else {
            // If the startup detection is opened, the Exception is thrown directly.
            boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
                    && url.getParameter(Constants.CHECK_KEY, true);
            boolean skipFailback = t instanceof SkipFailbackWrapperException;
            if (check || skipFailback) {
                if (skipFailback) {
                    t = t.getCause();
                }
                throw new IllegalStateException("Failed to subscribe " + url + ", cause: " + t.getMessage(), t);
            } else {
                logger.error("Failed to subscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t);
            }
        }

        // Record a failed registration request to a failed list, retry regularly
        addFailedSubscribed(url, listener);
    }
}
DubboRegistry
@Override
protected void doSubscribe(URL url, NotifyListener listener) {
    registryService.subscribe(url, listener);远程调用注册中心服务
}

 
SimpleRegistryService
@Override
public void subscribe(String service, URL url, NotifyListener listener) {
    //client host+port 10.0.0.1:7001
    String client = RpcContext.getContext().getRemoteAddressString();
    if (logger.isInfoEnabled()) {
        logger.info("[subscribe] service: " + service + ",client:" + client);
    }
    //获取目前该服务的 服务名称+分组+版本号 对应的所有提供者信息
    List<URL> urls = getRegistered().get(service);
    //针对订阅注册中心本身
    if ((RegistryService.class.getName() + ":0.0.0").equals(service)
            && (urls == null || urls.size() == 0)) {
        //将注册中心本身注册到提供服务的列表节点上
        register(service, new URL("dubbo",
                NetUtils.getLocalHost(),
                RpcContext.getContext().getLocalPort(),
                org.apache.dubbo.registry.RegistryService.class.getName(),
                url.getParameters()));
        //这里应该为配置的过个注册中心本身
        List<String> rs = registries;
        if (rs != null && rs.size() > 0) {
            for (String registry : rs) {
                register(service, UrlUtils.parseURL(registry, url.getParameters()));
            }
        }
    }
    //将订阅监听绑定
    super.subscribe(service, url, listener);
    //远端监听器,推送;
    Map<String, NotifyListener> listeners = remoteListeners.get(client);
    if (listeners == null) {
        remoteListeners.putIfAbsent(client, new ConcurrentHashMap<String, NotifyListener>());
        listeners = remoteListeners.get(client);
    }
    listeners.put(service, listener);
    urls = getRegistered().get(service);
    if (urls != null && urls.size() > 0) {
        listener.notify(urls);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

icool_ali

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值