Le centre d'enregistrement de l'analyse du code source dubbo

Préparation du gardien de zoo:

  • Téléchargez Zookeeper côté serveur (il y a une fosse ici, ne téléchargez pas apache-zookeeper-3.5.5.tar.gz): http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.5/apache- gardien de zoo- 3.5.5-bin.tar.gz
  • Copiez {zookeeper_base} \ conf \ zoo_sample.cfg dans le répertoire courant et renommez-le en zoo.cfg
  • Démarrez {zookeeper_base} \ bin \ zkServer.cmd

Relation d'héritage de classe:

  • RegistryService fournit 5 interfaces: register register (URL url), unregister unregister (URL url), subscribe (URL url, NotifyListener listener), unsubscribe unsubscribe (URL url, NotifyListener listener), lookup (URL url).
  • FailbackRegistry est la classe d'implémentation de RegistryService, qui est responsable de la relance des échecs d'abonnement et des échecs de désabonnement (réessayez périodiquement à l'aide de tâches chronométrées). Il définit également les méthodes abstraites doRegister (URL url), doUnregister (URL url), doSubscribe (URL url, écouteur NotifyListener), doUnsubscribe (URL url, écouteur NotifyListener).
  • ZookeeperRegistry est la classe d'implémentation de la classe abstraite FailbackRegistry, qui implémente les méthodes d'enregistrement, d'annulation, d'abonnement et d'annulation.

Zookeeper est un registre, responsable de l'enregistrement et de la découverte des informations de configuration. Dans l'architecture de dubbo, il s'agit de l'une des implémentations de l'enregistrement et de la découverte de services, qui est principalement responsable de l'exposition de l'interface de service. Grâce à la configuration des nœuds, les consommateurs peuvent trouver des fournisseurs de services. Analysons le code source de ZookeeperRegistry.

// 服务注册时,创建节点
protected void doRegister(URL url) {
    
    
    try {
    
    
        // ZookeeperClient zkClient
        // 后面会解析
        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);
    }
}

// 服务解注册,删除节点
protected void doUnregister(URL url) {
    
    
    try {
    
    
        // ZookeeperClient zkClient
        // 后面会解析
        zkClient.delete(toUrlPath(url));
    } catch (Throwable e) {
    
    
        throw new RpcException("Failed to unregister " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
    }
}

// 服务订阅
// ZookeeperRegistry#doSubscribe(final URL url, final NotifyListener listener)
protected void doSubscribe(final URL url, final NotifyListener listener) {
    
    
    try {
    
    
        if (Constants.ANY_VALUE.equals(url.getServiceInterface())) {
    
     // 订阅所有节点
            String root = toRootPath();
            ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
            if (listeners == null) {
    
    
                zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, ChildListener>());
                listeners = zkListeners.get(url);
            }
            ChildListener zkListener = listeners.get(listener);
            if (zkListener == null) {
    
    
                listeners.putIfAbsent(listener, new ChildListener() {
    
    
                    @Override
                    public void childChanged(String parentPath, List<String> currentChilds) {
    
    
                        for (String child : currentChilds) {
    
    
                            child = URL.decode(child);
                            if (!anyServices.contains(child)) {
    
    
                                anyServices.add(child);
                                subscribe(url.setPath(child).addParameters(Constants.INTERFACE_KEY, child,
                                        Constants.CHECK_KEY, String.valueOf(false)), listener);
                            }
                        }
                    }
                });
                zkListener = listeners.get(listener);
            }
            zkClient.create(root, false);
            List<String> services = zkClient.addChildListener(root, zkListener);
            if (services != null && !services.isEmpty()) {
    
    
                for (String service : services) {
    
    
                    service = URL.decode(service);
                    anyServices.add(service);
                    subscribe(url.setPath(service).addParameters(Constants.INTERFACE_KEY, service,
                            Constants.CHECK_KEY, String.valueOf(false)), listener);
                }
            }
        } else {
    
     // 订阅部分节点
            List<URL> urls = new ArrayList<URL>();
            for (String path : toCategoriesPath(url)) {
    
    
                // ConcurrentMap<URL, ConcurrentMap<NotifyListener, ChildListener>> zkListeners
                // 一个URL有一个ConcurrentMap<NotifyListener, ChildListener>
                // NotifyListener的实现类如RegistryDirectory
                // ChildListener对RegistryDirectory配置变动的监听,在其childChanged()对业务进行处理
                ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
                if (listeners == null) {
    
    
                    zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, ChildListener>());
                    listeners = zkListeners.get(url);
                }
                // 
                ChildListener zkListener = listeners.get(listener);
                // RegistryDirectory
                if (zkListener == null) {
    
    
                    // 创建监听器,监听节点变化
                    listeners.putIfAbsent(listener, new ChildListener() {
    
    
                        @Override
                        public void childChanged(String parentPath, List<String> currentChilds) {
    
    
                            // 有变更时会调用RegistryDirectory#notify(List<URL>)
                            ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));
                        }
                    });
                    zkListener = listeners.get(listener);
                }
                // 创建持久化节点
                zkClient.create(path, false);
                // 为节点添加监听
                // 最终调用CuratorFramework#getChildren()#usingWatcher(listener)#forPath(path)进行监听
                List<String> children = zkClient.addChildListener(path, zkListener);
                if (children != null) {
    
    
                    urls.addAll(toUrlsWithEmpty(url, path, children));
                }
            }
            // 订阅时,会调用RegistryDirectory#notify(List<URL>)初始化
            notify(url, listener, urls);
        }
    } catch (Throwable e) {
    
    
        throw new RpcException("Failed to subscribe " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
    }
}

// 取消订阅
protected void doUnsubscribe(URL url, NotifyListener listener) {
    
    
    ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
    if (listeners != null) {
    
    
        ChildListener zkListener = listeners.get(listener);
        if (zkListener != null) {
    
    
            if (Constants.ANY_VALUE.equals(url.getServiceInterface())) {
    
     // 订阅所有节点
                String root = toRootPath();
                zkClient.removeChildListener(root, zkListener);
            } else {
    
    
                for (String path : toCategoriesPath(url)) {
    
    
                    // 删除监听
                    // ((CuratorWatcherImpl) listener).unwatch()
                    zkClient.removeChildListener(path, zkListener);
                }
            }
        }
    }
}

Jetons un coup d'œil aux opérations de création, de suppression et de surveillance des nœuds de ZookeeperClient.

// 递归创建节点
// 除了叶节点是临时节点,其余节点都是永久节点(叶节点数据会定期更新可用的服务)
// eg. /dubbo/com.alibaba.dubbo.demo.DemoService/providers/dubbo%3A%2F%2F10.0.75.1%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26bean.name%3Dcom.alibaba.dubbo.demo.DemoService%26dubbo%3D2.0.2%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D7160%26side%3Dprovider%26timestamp%3D1567860977014
// 创建节点有2种实现:CuratorZookeeperClient和ZkclientZookeeperClient,默认使用CuratorZookeeperClient实现
// AbstractZookeeperClient.create(String path, boolean ephemeral)
public void create(String path, boolean ephemeral) {
    
    
    if (!ephemeral) {
    
     // 非临时节点
        if (checkExists(path)) {
    
     // 已存在则不再创建
            return;
        }
    }
    int i = path.lastIndexOf('/');
    if (i > 0) {
    
     // 判断是否为最后一个
        // 递归创建节点
        create(path.substring(0, i), false);
    }
    if (ephemeral) {
    
     // 创建临时节点
        createEphemeral(path);
    } else {
    
     // 创建持久化节点
        createPersistent(path);
    }
}

// 为节点添加监听
public List<String> addChildListener(String path, final ChildListener listener) {
    
    
    ConcurrentMap<ChildListener, TargetChildListener> listeners = childListeners.get(path);
    if (listeners == null) {
    
    
        childListeners.putIfAbsent(path, new ConcurrentHashMap<ChildListener, TargetChildListener>());
        listeners = childListeners.get(path);
    }
    TargetChildListener targetListener = listeners.get(listener);
    if (targetListener == null) {
    
    
        listeners.putIfAbsent(listener, createTargetChildListener(path, listener));
        targetListener = listeners.get(listener);
    }
    // 调用子类添加监听
    // 默认实现是CuratorZookeeperClient#addTargetChildListener(path, targetListener)
    return addTargetChildListener(path, targetListener);
}

Je suppose que tu aimes

Origine blog.csdn.net/fomeiherz/article/details/100984679
conseillé
Classement