Dubbo服务注册源码分析

org.apache.dubbo.registry.integration.RegistryProtocol#export

服务在本地发布完成,那么接下去要进入服务的注册阶段:

final Registry registry = getRegistry(originInvoker);
final URL registeredProviderUrl = getUrlToRegistry(providerUrl, registryUrl);

// decide if we need to delay publish
boolean register = providerUrl.getParameter(REGISTER_KEY, true);
if (register) {
    register(registryUrl, registeredProviderUrl);
}

其中 getRegistry 主要是获取到一个注册器的实现,代码如下

protected Registry getRegistry(final Invoker<?> originInvoker) {
    URL registryUrl = getRegistryUrl(originInvoker);
    return registryFactory.getRegistry(registryUrl);
}

然后这里应该进入 ZookeeperRegistryFactory#getRegistry ,但是 RegistryFactory 拓展点存在包装类 RegistryFactoryWrapper ,所以这里先走 RegistryFactoryWrapper#getRegistry ,然后走 ZookeeperRegistryFactory#getRegistry 。由于本类未实现,则进入父类 AbstractRegistryFactory#getRegistry ,然后调用 ZookeeperRegistryFactory#createRegistry,返回一个 ListenerRegistryWrapper(ZookeeperRegistry)

RegistryProtocol#register

private void register(URL registryUrl, URL registeredProviderUrl) {
    Registry registry = registryFactory.getRegistry(registryUrl);
    registry.register(registeredProviderUrl);
}

这里跟上面一样的逻辑,然后一定要走 ZookeeperRegistry#register ,但是本类中也未实现 ,走父类 FailbackRegistry#register

public void register(URL url) {
    if (!acceptable(url)) {
        logger.info("URL " + url + " will not be registered to Registry. Registry " + url + " does not accept service of this protocol type.");
        return;
    }
    // 调用父类注册,缓存添加
    super.register(url);
    removeFailedRegistered(url);
    removeFailedUnregistered(url);
    try {
        // Sending a registration request to the server side
        // 注册
        doRegister(url);
    } catch (Exception e) {
        Throwable t = e;

        // 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)
            && !CONSUMER_PROTOCOL.equals(url.getProtocol());
        boolean skipFailback = t instanceof SkipFailbackWrapperException;
        // 是否启动检查
        if (check || skipFailback) {
            if (skipFailback) {
                t = t.getCause();
            }
            throw new IllegalStateException("Failed to register " + url + " to registry " + getUrl().getAddress() + ", cause: " + t.getMessage(), t);
        } else {
            logger.error("Failed to register " + url + ", waiting for retry, cause: " + t.getMessage(), t);
        }

        // Record a failed registration request to a failed list, retry regularly
        // 失败重试
        addFailedRegistered(url);
    }
}

ZookeeperRegistry#doRegister

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

服务到此注册完毕,ZK 服务端即出现服务注册相关的信息。最后附上服务发布、注册的主要流程图

原文地址:https://www.cnblogs.com/snail-gao/p/14210838.html