El centro de registro de análisis de código fuente de dubbo

Preparación del cuidador del zoológico:

  • Descargue el lado del servidor Zookeeper (hay un pozo aquí, no descargue apache-zookeeper-3.5.5.tar.gz): http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.5/apache- guardián del zoológico- 3.5.5-bin.tar.gz
  • Copie {zookeeper_base} \ conf \ zoo_sample.cfg en el directorio actual y cámbiele el nombre a zoo.cfg
  • Inicie {zookeeper_base} \ bin \ zkServer.cmd

Relación de herencia de clases:

  • RegistryService proporciona 5 interfaces: registro de registro (URL url), anular registro anular registro (URL URL), suscribirse (URL URL, oyente NotifyListener), cancelar suscripción cancelar suscripción (URL URL, oyente NotifyListener), búsqueda (URL URL).
  • FailbackRegistry es la clase de implementación de RegistryService, que es responsable de reintentar las fallas de suscripción y las fallas de cancelación de suscripción (reintentar periódicamente utilizando tareas programadas). También define los métodos abstractos doRegister (URL url), doUnregister (URL url), doSubscribe (URL URL, oyente NotifyListener), doUnsubscribe (URL url, oyente NotifyListener).
  • ZookeeperRegistry es la clase de implementación de la clase abstracta FailbackRegistry, que implementa los métodos de registro, cancelación, suscripción y cancelación.

Zookeeper es un registro, responsable del registro y descubrimiento de información de configuración. En la arquitectura de dubbo, es una de las implementaciones de registro y descubrimiento de servicios, que es principalmente responsable de la exposición de la interfaz de servicio.A través de la configuración de nodos, los consumidores pueden encontrar proveedores de servicios. Analicemos el código fuente 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);
                }
            }
        }
    }
}

Echemos un vistazo a las operaciones de creación, eliminación y monitoreo de nodos 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);
}

Supongo que te gusta

Origin blog.csdn.net/fomeiherz/article/details/100984679
Recomendado
Clasificación