dubbo技术内幕十五 ReferenceBean refer向zk写了什么

上一章的中有讲到ServiceBean在export的过程中向zk写入的信息,这一章看下ReferenceBean在refer的过程中,向zk写的数据,已经监听了哪些变更。
我们直接的拉到ReferenceBean的getObject方法,如下

 public Object getObject() throws Exception {
        return get();
    }

直接的跟到ReferenceConfig类的init方法里面的最重要的一句

 ref = createProxy(map);

而在createProxy方法里面,最重要的一句,如下

 invoker = refprotocol.refer(interfaceClass, urls.get(0));

我们直接的跟到RegistryProtocol的refer方法里面的最后一句,如下

return doRefer(cluster, registry, type, url);

而在doRefer里面摘取重要的语句如下

  //构造url
  URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, parameters.remove(Constants.REGISTER_IP_KEY), 0, type.getName(), parameters);
        if (!Constants.ANY_VALUE.equals(url.getServiceInterface())
                && url.getParameter(Constants.REGISTER_KEY, true)) {
            URL registeredConsumerUrl = getRegisteredConsumerUrl(subscribeUrl, url);
            //注册消费者信息
            registry.register(registeredConsumerUrl);
            directory.setRegisteredConsumerUrl(registeredConsumerUrl);
        }
        //订阅指定zk目录的信息
        directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,
                Constants.PROVIDERS_CATEGORY
                        + "," + Constants.CONFIGURATORS_CATEGORY
                        + "," + Constants.ROUTERS_CATEGORY));

其中

 registry.register(registeredConsumerUrl);

会调用到ZookeeperRegistry的doRegister方法,如下

    protected void doRegister(URL url) {
        try {
            zkClient.create(toUrlPath(url), url.getParameter(Constants.DYNAMIC_KEY, true));
        } catch (Throwable e) {
            throw new RpcException("Failed to register " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
        }
    }

其中toUrlPath(url)返回如下


image.png

等于说我们在/dubbo/com.starunion.transport.service.TransportService/consumers目录下添加了该dubbo服务的消费者信息。

directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,
                Constants.PROVIDERS_CATEGORY
                        + "," + Constants.CONFIGURATORS_CATEGORY
                        + "," + Constants.ROUTERS_CATEGORY));

一直跟到ZookeeperRegistry的doSubscribe方法,核心代码如下

 for (String path : toCategoriesPath(url)) {
                    ConcurrentMap listeners = zkListeners.get(url);
                    if (listeners == null) {
                        zkListeners.putIfAbsent(url, new ConcurrentHashMap());
                        listeners = zkListeners.get(url);
                    }
                    ChildListener zkListener = listeners.get(listener);
                    if (zkListener == null) {
                        listeners.putIfAbsent(listener, new ChildListener() {
                            @Override
                            public void childChanged(String parentPath, List currentChilds) {
                                ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));
                            }
                        });
                        zkListener = listeners.get(listener);
                    }
                    zkClient.create(path, false);
                    List children = zkClient.addChildListener(path, zkListener);
                    if (children != null) {
                        urls.addAll(toUrlsWithEmpty(url, path, children));
                    }
                }
                notify(url, listener, urls);
            }

其中 toCategoriesPath(url)返回如下


image.png

所以消费端订阅的zk节点为 providers(实时的监听providers的变化),
configurators(实时的监听配置变化),routers(实时的监听路由配置的变化)

如果打开dubbo的后台页面的话,ReferenceBean关注的功能如下


image.png

你可能感兴趣的:(dubbo技术内幕十五 ReferenceBean refer向zk写了什么)