【Dubbo源码阅读系列】服务暴露之远程暴露 (4)

上面我们已经聊完了 doLocalExport() 方法,继续看 export() 方法的后半部分:

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

这里的 registryFactory 为 RegistryFactory$Adaptive(Dubbo 源码中充斥了大量 SPI 扩展机制的使用,这里不再赘述)。总之我们获取到的扩展类为 ZookeeperRegistryFactory ,ZookeeperRegistryFactory 继承自 AbstractRegistryFactory 类。因此最后调用的是 AbstractRegistryFactory 类的 getRegistry() 方法。

@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.toServiceStringWithoutResolving(); // 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(); } }

方法比较简单,直接看重点方法 createRegistry(url)。createRegistry() 是一个抽象方法,会根据 url 来调用具体的实现方法,这里我们用 ZookeeperRegistryFactory 类进行分析。

public class ZookeeperRegistryFactory extends AbstractRegistryFactory { ... public Registry createRegistry(URL url) { return new ZookeeperRegistry(url, zookeeperTransporter); } ... } public class ZookeeperRegistry extends FailbackRegistry { ... public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter) { super(url); if (url.isAnyHost()) { throw new IllegalStateException("registry address == null"); } String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT); if (!group.startsWith(Constants.PATH_SEPARATOR)) { group = Constants.PATH_SEPARATOR + group; } this.root = group; zkClient = zookeeperTransporter.connect(url); zkClient.addStateListener(new StateListener() { @Override public void stateChanged(int state) { if (state == RECONNECTED) { try { recover(); } catch (Exception e) { logger.error(e.getMessage(), e); } } } }); } ... }

ZookeeperRegistryFactory 类的 createRegistry() 方法会调用 ZookeeperRegistry 类的构造方法新建 ZookeeperRegistry 实例并返回。而 ZookeeperRegistry 类的构造方法会先调用父类 FailbackRegistry 的构造方法再执行后续操作。先看 FailbackRegistry 构造方法:

public abstract class FailbackRegistry extends AbstractRegistry { ... public FailbackRegistry(URL url) { super(url); this.retryPeriod = url.getParameter(Constants.REGISTRY_RETRY_PERIOD_KEY, Constants.DEFAULT_REGISTRY_RETRY_PERIOD); this.retryFuture = retryExecutor.scheduleWithFixedDelay(new Runnable() { @Override public void run() { // Check and connect to the registry try { // 延迟重试 retry(); } catch (Throwable t) { // Defensive fault tolerance logger.error("Unexpected error occur at failed retry, cause: " + t.getMessage(), t); } } }, retryPeriod, retryPeriod, TimeUnit.MILLISECONDS); } ... }

在 FailbackRegistry 构造方法中有一个延迟重试方法 retry(),如果发现失败集合 failedRegistered、failedUnregistered、failedSubscribed、failedUnsubscribed、failedNotified 不为空,会进行重试操作。
继续看 ZookeeperRegistry 类的构造方法:

public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter) { ... zkClient = zookeeperTransporter.connect(url); zkClient.addStateListener(new StateListener() { @Override public void stateChanged(int state) { if (state == RECONNECTED) { try { recover(); } catch (Exception e) { logger.error(e.getMessage(), e); } } } }); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyxywf.html