From ed48f9a816c4a7ccef9e1535df55212846ab1ee2 Mon Sep 17 00:00:00 2001 From: AmyliaY <471816751@qq.com> Date: Sun, 19 Apr 2020 15:36:27 +0800 Subject: [PATCH] =?UTF-8?q?Dubbo=E6=B3=A8=E5=86=8C=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=20=E6=BA=90=E7=A0=81=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Dubbo/registry/Dubbo注册中心.md | 2172 ++++++++++++++++- images/Dubbo/Dubbo原理图.png | Bin 0 -> 71278 bytes images/Dubbo/RegistryFactory组件类图.png | Bin 0 -> 49134 bytes images/Dubbo/Registry组件类图.png | Bin 0 -> 66450 bytes .../Dubbo/dubbo-registry模块结构图.png | Bin 0 -> 21661 bytes 5 files changed, 2171 insertions(+), 1 deletion(-) create mode 100644 images/Dubbo/Dubbo原理图.png create mode 100644 images/Dubbo/RegistryFactory组件类图.png create mode 100644 images/Dubbo/Registry组件类图.png create mode 100644 images/Dubbo/dubbo-registry模块结构图.png diff --git a/docs/Dubbo/registry/Dubbo注册中心.md b/docs/Dubbo/registry/Dubbo注册中心.md index fcb5dbe..2e94ce0 100644 --- a/docs/Dubbo/registry/Dubbo注册中心.md +++ b/docs/Dubbo/registry/Dubbo注册中心.md @@ -1 +1,2171 @@ -努力编写中... \ No newline at end of file +## 注册中心在Dubbo中的作用 +服务治理框架可以大致分为 服务通信 和 服务管理 两部分,服务管理可以分为服务注册、服务订阅以及服务发现,服务提供者Provider 会往注册中心注册服务,而消费者Consumer 会从注册中心中订阅自己关注的服务,并在关注的服务发生变更时 得到注册中心的通知。Provider、Consumer以及Registry之间的依赖关系 如下图所示。 + +![avatar](/images/Dubbo/Dubbo原理图.png) + +## dubbo-registry 模块 结构分析 +dubbo的注册中心有多种实现方案,如:zookeeper、redis、multicast等,本章先看一下 dubbo-registry 模块的核心部分 dubbo-registry-api,具体实现部分放到下章来讲。dubbo-registry模块 的结构如下图所示。 + +![avatar](/images/Dubbo/dubbo-registry模块结构图.png) + +### Registry 核心组件类图 +典型的 接口 -> 抽象类 -> 实现类 的结构设计,如下图所示。 + +![avatar](/images/Dubbo/Registry组件类图.png) + +既然有Registry组件,那么按照很多框架的套路,肯定也有一个用于获取 Registry实例的RegistryFactory,其中用到了工厂方法模式,不同的工厂类用于获取不同类型的实例。其类图结构如下。 + +![avatar](/images/Dubbo/RegistryFactory组件类图.png) + +## 源码详解 +根据上面的类图,我们开始从上往下 详解dubbo中对于注册中心的设计以及实现。 +### RegistryService 接口 +RegistryService 是注册中心模块的服务接口,定义了注册、取消注册、订阅、取消订阅以及查询符合条件的已注册数据 等方法。这里统一说明一下URL,dubbo是以总线模式来时刻传递和保存配置信息的,配置信息都被放在URL上进行传递,随时可以取得相关配置信息,而这里提到了URL有别的作用,就是作为类似于节点的作用,首先服务提供者(Provider)启动时需要提供服务,就会向注册中心写下自己的URL地址。然后消费者启动时需要去订阅该服务,则会订阅Provider注册的地址,并且消费者也会写下自己的URL。 +```java +/** + * RegistryService. (SPI, Prototype, ThreadSafe) + * + * 注册中心服务接口 + */ +public interface RegistryService { + + /** + * 注册数据,比如:提供者地址,消费者地址,路由规则,覆盖规则 等数据。 + *

+ * 注册需处理契约:
+ * 1. 当URL设置了check=false时,注册失败后不报错,在后台定时重试,否则抛出异常。
+ * 2. 当URL设置了dynamic=false参数,则需持久存储,否则,当注册者出现断电等情况异常退出时,需自动删除。
+ * 3. 当URL设置了category=routers时,表示分类存储,缺省类别为providers,可按分类部分通知数据。
+ * 4. 当注册中心重启,网络抖动,不能丢失数据,包括断线自动删除数据。
+ * 5. 允许URI相同但参数不同的URL并存,不能覆盖。
+ * + * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin + */ + void register(URL url); + + /** + * 取消注册. + *

+ * 取消注册需处理契约:
+ * 1. 如果是dynamic=false的持久存储数据,找不到注册数据,则抛IllegalStateException,否则忽略。
+ * 2. 按全URL匹配取消注册。
+ * + * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin + */ + void unregister(URL url); + + /** + * 订阅符合条件的已注册数据,当有注册数据变更时自动推送. + *

+ * 订阅需处理契约:
+ * 1. 当URL设置了check=false时,订阅失败后不报错,在后台定时重试。
+ * 2. 当URL设置了category=routers,只通知指定分类的数据,多个分类用逗号分隔,并允许星号通配,表示订阅所有分类数据。
+ * 3. 允许以interface,group,version,classifier作为条件查询,如:interface=com.alibaba.foo.BarService&version=1.0.0
+ * 4. 并且查询条件允许星号通配,订阅所有接口的所有分组的所有版本,或:interface=*&group=*&version=*&classifier=*
+ * 5. 当注册中心重启,网络抖动,需自动恢复订阅请求。
+ * 6. 允许URI相同但参数不同的URL并存,不能覆盖。
+ * 7. 必须阻塞订阅过程,等第一次通知完后再返回。
+ * + * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin + * @param listener 变更事件监听器,不允许为空 + */ + void subscribe(URL url, NotifyListener listener); + + /** + * 取消订阅. + *

+ * 取消订阅需处理契约:
+ * 1. 如果没有订阅,直接忽略。
+ * 2. 按全URL匹配取消订阅。
+ * + * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin + * @param listener 变更事件监听器,不允许为空 + */ + void unsubscribe(URL url, NotifyListener listener); + + /** + * 查询符合条件的已注册数据,与订阅的推模式相对应,这里为拉模式,只返回一次结果。 + * + * @param url 查询条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin + * @return 已注册信息列表,可能为空,含义同{@link com.alibaba.dubbo.registry.NotifyListener#notify(List)}的参数。 + * @see com.alibaba.dubbo.registry.NotifyListener#notify(List) + */ + List lookup(URL url); +} +``` + +### Registry 接口 +注册中心接口,把节点Node 以及注册中心服务RegistryService 的方法整合在了这个接口里面。该接口并没有自己的方法,就是继承了Node和RegistryService接口。这里的Node是节点的接口,里面协定了关于节点的一些操作方法,源码如下。 +```java +/** + * 注册中心接口 + */ +public interface Registry extends Node, RegistryService { +} + +public interface Node { + //获得节点地址 + URL getUrl(); + //判断节点是否可用 + boolean isAvailable(); + //销毁节点 + void destroy(); +} +``` + +### AbstractRegistry 抽象类 +实现了Registry接口的抽象类。为了减轻注册中心的压力,该抽象类把本地URL缓存到了property文件中,并且实现了注册中心的注册、订阅等方法。 +```java +/** + * 实现了Registry接口的抽象类,实现了如下方法: + * + * 1、通用的注册、订阅、查询、通知等方法 + * 2、读取和持久化注册数据到文件,以 properties 格式存储 + */ +public abstract class AbstractRegistry implements Registry { + + // URL地址分隔符,用于文件缓存中,服务提供者URL分隔 + private static final char URL_SEPARATOR = ' '; + // URL地址分隔正则表达式,用于解析文件缓存中服务提供者URL列表 + private static final String URL_SPLIT = "\\s+"; + + // Log output + protected final Logger logger = LoggerFactory.getLogger(getClass()); + /** + * 本地磁盘缓存。 + * 1. 其中特殊的 key 值 .registies 记录注册中心列表 TODO 8019 芋艿,特殊的 key 是 + * 2. 其它均为 {@link #notified} 服务提供者列表 + */ + private final Properties properties = new Properties(); + /** + * 注册中心缓存写入执行器。 + * 线程数=1 + */ + // File cache timing writing + private final ExecutorService registryCacheExecutor = Executors.newFixedThreadPool(1, new NamedThreadFactory("DubboSaveRegistryCache", true)); + /** + * 是否同步保存文件 + */ + private final boolean syncSaveFile; + /** + * 数据版本号 + */ + private final AtomicLong lastCacheChanged = new AtomicLong(); + /** + * 已注册 URL 集合。 + * 注册的 URL 可以是服务提供者的,也可以是服务消费者的 + */ + private final Set registered = new ConcurrentHashSet(); + /** + * 订阅 URL 的监听器集合 + * key:订阅者的 URL ,例如消费者的 URL + */ + private final ConcurrentMap> subscribed = new ConcurrentHashMap>(); + /** + * 被通知的 URL 集合 + * key1:消费者的 URL ,例如消费者的 URL ,和 {@link #subscribed} 的键一致 + * key2:分类,例如:providers、consumers、routes、configurators。【实际无 consumers ,因为消费者不会去订阅另外的消费者的列表】 + * 在 {@link Constants} 中,以 "_CATEGORY" 结尾 + */ + private final ConcurrentMap>> notified = new ConcurrentHashMap>>(); + /** + * 注册中心 URL + */ + private URL registryUrl; + /** + * 本地磁盘缓存文件,缓存注册中心的数据 + */ + private File file; + /** + * 是否销毁 + */ + private AtomicBoolean destroyed = new AtomicBoolean(false); + + public AbstractRegistry(URL url) { + setUrl(url); + // Start file save timer + syncSaveFile = url.getParameter(Constants.REGISTRY_FILESAVE_SYNC_KEY, false); + // 获得 `file` + String filename = url.getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/.dubbo/dubbo-registry-" + url.getParameter(Constants.APPLICATION_KEY) + "-" + url.getAddress() + ".cache"); + File file = null; + if (ConfigUtils.isNotEmpty(filename)) { + file = new File(filename); + if (!file.exists() && file.getParentFile() != null && !file.getParentFile().exists()) { + if (!file.getParentFile().mkdirs()) { + throw new IllegalArgumentException("Invalid registry store file " + file + ", cause: Failed to create directory " + file.getParentFile() + "!"); + } + } + } + this.file = file; + // 加载本地磁盘缓存文件到内存缓存 + loadProperties(); + // 通知监听器,URL 变化结果 + notify(url.getBackupUrls()); // 【TODO 8020】为什么构造方法,要通知,连监听器都没注册 + } + + protected static List filterEmpty(URL url, List urls) { + if (urls == null || urls.isEmpty()) { + List result = new ArrayList(1); + result.add(url.setProtocol(Constants.EMPTY_PROTOCOL)); + return result; + } + return urls; + } + + @Override + public URL getUrl() { + return registryUrl; + } + + protected void setUrl(URL url) { + if (url == null) { + throw new IllegalArgumentException("registry url == null"); + } + this.registryUrl = url; + } + + public Set getRegistered() { + return registered; + } + + public Map> getSubscribed() { + return subscribed; + } + + public Map>> getNotified() { + return notified; + } + + public File getCacheFile() { + return file; + } + + public Properties getCacheProperties() { + return properties; + } + + public AtomicLong getLastCacheChanged() { + return lastCacheChanged; + } + + /** + * 保存内存缓存到本地磁盘缓存文件,即 {@link #properties} => {@link #file} + * + * @param version 数据版本号 + */ + public void doSaveProperties(long version) { + if (version < lastCacheChanged.get()) { + return; + } + if (file == null) { + return; + } + // Save + try { + // 创建 .lock 文件 + File lockfile = new File(file.getAbsolutePath() + ".lock"); + if (!lockfile.exists()) { + lockfile.createNewFile(); + } + // 随机读写文件操作 + RandomAccessFile raf = new RandomAccessFile(lockfile, "rw"); + try { + FileChannel channel = raf.getChannel(); + try { + // 获得文件锁 + FileLock lock = channel.tryLock(); + // 获取失败 + if (lock == null) { + throw new IOException("Can not lock the registry cache file " + file.getAbsolutePath() + ", ignore and retry later, maybe multi java process use the file, please config: dubbo.registry.file=xxx.properties"); + } + // 获取成功,进行保存 + // Save + try { + if (!file.exists()) { + file.createNewFile(); + } + FileOutputStream outputFile = new FileOutputStream(file); + try { + properties.store(outputFile, "Dubbo Registry Cache"); + } finally { + outputFile.close(); + } + // 释放文件锁 + } finally { + lock.release(); + } + // 释放文件 Channel + } finally { + channel.close(); + } + // 释放随机读写文件操作 + } finally { + raf.close(); + } + } catch (Throwable e) { + // 版本号过小,不保存 + if (version < lastCacheChanged.get()) { + return; + // 重新异步保存,一般情况下为上面的获取锁失败抛出的异常。通过这样的方式,达到保存成功。 + } else { + registryCacheExecutor.execute(new SaveProperties(lastCacheChanged.incrementAndGet())); + } + logger.warn("Failed to save registry store file, cause: " + e.getMessage(), e); + } + } + + /** + * 加载本地磁盘缓存文件到内存缓存,即 {@link #file} => {@link #properties} + */ + private void loadProperties() { + if (file != null && file.exists()) { + InputStream in = null; + try { + // 文件流 + in = new FileInputStream(file); + // 读取文件流 + properties.load(in); + if (logger.isInfoEnabled()) { + logger.info("Load registry store file " + file + ", data: " + properties); + } + } catch (Throwable e) { + logger.warn("Failed to load registry store file " + file, e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + logger.warn(e.getMessage(), e); + } + } + } + } + } + + /** + * 从 `properties` 中获得缓存的 URL 集合 + * + * @param url URL + * @return URL 集合 + */ + public List getCacheUrls(URL url) { + for (Map.Entry entry : properties.entrySet()) { + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + if (key != null && key.length() > 0 // 非空 + && key.equals(url.getServiceKey()) // 服务键匹配 + && (Character.isLetter(key.charAt(0)) || key.charAt(0) == '_') // TODO 芋艿,_ 是什么 + && value != null && value.length() > 0) { // 值非空 + String[] arr = value.trim().split(URL_SPLIT); + List urls = new ArrayList(); + for (String u : arr) { + urls.add(URL.valueOf(u)); + } + return urls; + } + } + return null; + } + + @Override + public List lookup(URL url) { + List result = new ArrayList(); + Map> notifiedUrls = getNotified().get(url); + // 有数据,遍历数据获得 + if (notifiedUrls != null && notifiedUrls.size() > 0) { + // 遍历 + for (List urls : notifiedUrls.values()) { + for (URL u : urls) { + if (!Constants.EMPTY_PROTOCOL.equals(u.getProtocol())) { + result.add(u); + } + } + } + // 无数据,通过发起订阅的方式得到数据后,遍历数据获得 + } else { + // 创建 NotifyListener 对象 + final AtomicReference> reference = new AtomicReference>(); + NotifyListener listener = new NotifyListener() { + public void notify(List urls) { + reference.set(urls); + } + }; + // 订阅获得数据 + subscribe(url, listener); // Subscribe logic guarantees the first notify to return + List urls = reference.get(); + // 遍历 + if (urls != null && !urls.isEmpty()) { + for (URL u : urls) { + if (!Constants.EMPTY_PROTOCOL.equals(u.getProtocol())) { + result.add(u); + } + } + } + } + return result; + } + + @Override + public void register(URL url) { + if (url == null) { + throw new IllegalArgumentException("register url == null"); + } + if (logger.isInfoEnabled()) { + logger.info("Register: " + url); + } + // 添加到 registered 集合 + registered.add(url); + } + + @Override + public void unregister(URL url) { + if (url == null) { + throw new IllegalArgumentException("unregister url == null"); + } + if (logger.isInfoEnabled()) { + logger.info("Unregister: " + url); + } + // 移除出 registered 集合 + registered.remove(url); + } + + @Override + public void subscribe(URL url, NotifyListener listener) { + if (url == null) { + throw new IllegalArgumentException("subscribe url == null"); + } + if (listener == null) { + throw new IllegalArgumentException("subscribe listener == null"); + } + if (logger.isInfoEnabled()) { + logger.info("Subscribe: " + url); + } + // 添加到 subscribed 集合 + Set listeners = subscribed.get(url); + if (listeners == null) { + subscribed.putIfAbsent(url, new ConcurrentHashSet()); + listeners = subscribed.get(url); + } + listeners.add(listener); + } + + @Override + public void unsubscribe(URL url, NotifyListener listener) { + if (url == null) { + throw new IllegalArgumentException("unsubscribe url == null"); + } + if (listener == null) { + throw new IllegalArgumentException("unsubscribe listener == null"); + } + if (logger.isInfoEnabled()) { + logger.info("Unsubscribe: " + url); + } + // 移除出 subscribed 集合 + Set listeners = subscribed.get(url); + if (listeners != null) { + listeners.remove(listener); + } + } + + /** + * 恢复注册和订阅 + * + * @throws Exception 发生异常 + */ + protected void recover() throws Exception { + // register 恢复注册 + Set recoverRegistered = new HashSet(getRegistered()); + if (!recoverRegistered.isEmpty()) { + if (logger.isInfoEnabled()) { + logger.info("Recover register url " + recoverRegistered); + } + for (URL url : recoverRegistered) { + register(url); + } + } + // subscribe 恢复订阅 + Map> recoverSubscribed = new HashMap>(getSubscribed()); + if (!recoverSubscribed.isEmpty()) { + if (logger.isInfoEnabled()) { + logger.info("Recover subscribe url " + recoverSubscribed.keySet()); + } + for (Map.Entry> entry : recoverSubscribed.entrySet()) { + URL url = entry.getKey(); + for (NotifyListener listener : entry.getValue()) { + subscribe(url, listener); + } + } + } + } + + /** + * 通知监听器,URL 变化结果。 + * + * @param urls 通知的 URL 变化结果(全量数据) + */ + protected void notify(List urls) { + if (urls == null || urls.isEmpty()) return; + // 循环 `subscribed` ,通知监听器们 + for (Map.Entry> entry : getSubscribed().entrySet()) { + URL url = entry.getKey(); + // 匹配 + if (!UrlUtils.isMatch(url, urls.get(0))) { + continue; + } + // 通知监听器 + Set listeners = entry.getValue(); + if (listeners != null) { + for (NotifyListener listener : listeners) { + try { + notify(url, listener, filterEmpty(url, urls)); + } catch (Throwable t) { + logger.error("Failed to notify registry event, urls: " + urls + ", cause: " + t.getMessage(), t); + } + } + } + } + } + + /** + * 通知监听器,URL 变化结果。 + * + * 数据流向 `urls` => {@link #notified} => {@link #properties} => {@link #file} + * + * @param url 消费者 URL + * @param listener 监听器 + * @param urls 通知的 URL 变化结果(全量数据) + */ + protected void notify(URL url, NotifyListener listener, List urls) { + if (url == null) { + throw new IllegalArgumentException("notify url == null"); + } + if (listener == null) { + throw new IllegalArgumentException("notify listener == null"); + } + if ((urls == null || urls.isEmpty()) + && !Constants.ANY_VALUE.equals(url.getServiceInterface())) { + logger.warn("Ignore empty notify urls for subscribe url " + url); + return; + } + if (logger.isInfoEnabled()) { + logger.info("Notify urls for subscribe url " + url + ", urls: " + urls); + } + // 将 `urls` 按照 `url.parameter.category` 分类,添加到集合 + // 注意,特殊情况,使用 curator 连接 Zookeeper 时,若是服务消费者,连接断开,会出现 category=providers,configurations,routes + Map> result = new HashMap>(); + for (URL u : urls) { + if (UrlUtils.isMatch(url, u)) { + String category = u.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); + List categoryList = result.get(category); + if (categoryList == null) { + categoryList = new ArrayList(); + result.put(category, categoryList); + } + categoryList.add(u); + } + } + if (result.size() == 0) { + return; + } + // 获得消费者 URL 对应的在 `notified` 中,通知的 URL 变化结果(全量数据) + Map> categoryNotified = notified.get(url); + if (categoryNotified == null) { + notified.putIfAbsent(url, new ConcurrentHashMap>()); + categoryNotified = notified.get(url); + } + // 【按照分类循环】处理通知的 URL 变化结果(全量数据) + for (Map.Entry> entry : result.entrySet()) { + String category = entry.getKey(); + List categoryList = entry.getValue(); + // 覆盖到 `notified` + // 当某个分类的数据为空时,会依然有 urls 。其中 `urls[0].protocol = empty` ,通过这样的方式,处理所有服务提供者为空的情况。 + categoryNotified.put(category, categoryList); + // 保存到文件 + saveProperties(url); + // 通知监听器 + listener.notify(categoryList); + } + } + + /** + * 保存单个消费者 URL 对应,在 `notified` 的数据,到文件。 + * + * @param url 消费者 URL + */ + private void saveProperties(URL url) { + if (file == null) { + return; + } + + try { + // 拼接 URL + StringBuilder buf = new StringBuilder(); + Map> categoryNotified = notified.get(url); + if (categoryNotified != null) { + for (List us : categoryNotified.values()) { + for (URL u : us) { + if (buf.length() > 0) { + buf.append(URL_SEPARATOR); + } + buf.append(u.toFullString()); + } + } + } + // 设置到 properties 中 + properties.setProperty(url.getServiceKey(), buf.toString()); + // 增加数据版本号 + long version = lastCacheChanged.incrementAndGet(); + // 保存到文件 + if (syncSaveFile) { + doSaveProperties(version); + } else { + registryCacheExecutor.execute(new SaveProperties(version)); + } + } catch (Throwable t) { + logger.warn(t.getMessage(), t); + } + } + + /** + * 取消注册和订阅 + */ + @Override + public void destroy() { + // 已销毁,跳过 + if (!destroyed.compareAndSet(false, true)) { + return; + } + if (logger.isInfoEnabled()) { + logger.info("Destroy registry:" + getUrl()); + } + // 取消注册 + Set destroyRegistered = new HashSet(getRegistered()); + if (!destroyRegistered.isEmpty()) { + for (URL url : new HashSet(getRegistered())) { + if (url.getParameter(Constants.DYNAMIC_KEY, true)) { + try { + unregister(url); // 取消注册 + if (logger.isInfoEnabled()) { + logger.info("Destroy unregister url " + url); + } + } catch (Throwable t) { + logger.warn("Failed to unregister url " + url + " to registry " + getUrl() + " on destroy, cause: " + t.getMessage(), t); + } + } + } + } + // 取消订阅 + Map> destroySubscribed = new HashMap>(getSubscribed()); + if (!destroySubscribed.isEmpty()) { + for (Map.Entry> entry : destroySubscribed.entrySet()) { + URL url = entry.getKey(); + for (NotifyListener listener : entry.getValue()) { + try { + unsubscribe(url, listener); // 取消订阅 + if (logger.isInfoEnabled()) { + logger.info("Destroy unsubscribe url " + url); + } + } catch (Throwable t) { + logger.warn("Failed to unsubscribe url " + url + " to registry " + getUrl() + " on destroy, cause: " + t.getMessage(), t); + } + } + } + } + } + + public String toString() { + return getUrl().toString(); + } + + /** + * 保存配置的 Runnable任务 + */ + private class SaveProperties implements Runnable { + + /** + * 数据版本号 + */ + private long version; + + private SaveProperties(long version) { + this.version = version; + } + + public void run() { + doSaveProperties(version); + } + } +} +``` + +### FailbackRegistry 抽象类 +FailbackRegistry抽象类 继承了上面的 AbstractRegistry,AbstractRegistry中的注册、订阅等方法,实际上就是一些内存缓存的变化,而真正的注册订阅的实现逻辑在FailbackRegistry实现,并且FailbackRegistry提供了失败重试的机制。 +```java +/** + * 支持失败重试的 FailbackRegistry抽象类 + */ +public abstract class FailbackRegistry extends AbstractRegistry { + + /** + * 定时任务执行器 + */ + private final ScheduledExecutorService retryExecutor = Executors. + newScheduledThreadPool(1, new NamedThreadFactory("DubboRegistryFailedRetryTimer", true)); + + /** + * 失败重试定时器,定时检查是否有请求失败,如有,无限次重试 + */ + private final ScheduledFuture retryFuture; + /** + * 注册失败的 URL 集合 + */ + private final Set failedRegistered = new ConcurrentHashSet(); + /** + * 取消注册失败的 URL 集合 + */ + private final Set failedUnregistered = new ConcurrentHashSet(); + /** + * 订阅失败的监听器集合 + */ + private final ConcurrentMap> failedSubscribed = new ConcurrentHashMap>(); + /** + * 取消订阅失败的监听器集合 + */ + private final ConcurrentMap> failedUnsubscribed = new ConcurrentHashMap>(); + /** + * 通知失败的 URL 集合 + */ + private final ConcurrentMap>> failedNotified = new ConcurrentHashMap>>(); + + /** + * 是否销毁 + */ + private AtomicBoolean destroyed = new AtomicBoolean(false); + + public FailbackRegistry(URL url) { + super(url); + // 重试频率,单位:毫秒 + int retryPeriod = url.getParameter(Constants.REGISTRY_RETRY_PERIOD_KEY, Constants.DEFAULT_REGISTRY_RETRY_PERIOD); + // 创建失败重试定时器 + this.retryFuture = retryExecutor.scheduleWithFixedDelay(new Runnable() { + 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); + } + + public Future getRetryFuture() { + return retryFuture; + } + + public Set getFailedRegistered() { + return failedRegistered; + } + + public Set getFailedUnregistered() { + return failedUnregistered; + } + + public Map> getFailedSubscribed() { + return failedSubscribed; + } + + public Map> getFailedUnsubscribed() { + return failedUnsubscribed; + } + + public Map>> getFailedNotified() { + return failedNotified; + } + + /** + * 添加到 `failedSubscribed` + */ + private void addFailedSubscribed(URL url, NotifyListener listener) { + Set listeners = failedSubscribed.get(url); + if (listeners == null) { + failedSubscribed.putIfAbsent(url, new ConcurrentHashSet()); + listeners = failedSubscribed.get(url); + } + listeners.add(listener); + } + + /** + * 移除出 `failedSubscribed` `failedUnsubscribed` `failedNotified` + */ + private void removeFailedSubscribed(URL url, NotifyListener listener) { + // 移除出 `failedSubscribed` + Set listeners = failedSubscribed.get(url); + if (listeners != null) { + listeners.remove(listener); + } + // 移除出 `failedUnsubscribed` + listeners = failedUnsubscribed.get(url); + if (listeners != null) { + listeners.remove(listener); + } + // 移除出 `failedNotified` + Map> notified = failedNotified.get(url); + if (notified != null) { + notified.remove(listener); + } + } + + @Override + public void register(URL url) { + // 已销毁,跳过 + if (destroyed.get()){ + return; + } + // 添加到 `registered` 变量 + super.register(url); + // 移除出 `failedRegistered` `failedUnregistered` 变量 + failedRegistered.remove(url); + failedUnregistered.remove(url); + // 向注册中心发送注册请求 + try { + doRegister(url); + } catch (Exception e) { + Throwable t = e; + + // 如果开启了启动时检测,则直接抛出异常 + boolean check = getUrl().getParameter(Constants.CHECK_KEY, true) + && url.getParameter(Constants.CHECK_KEY, true) + && !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol()); // 非消费者。消费者会在 `ReferenceConfig#createProxy(...)` 方法中,调用 `Invoker#avalible()` 方法,进行检查。 + 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); + } + + // 将失败的注册请求记录到 `failedRegistered`,定时重试 + failedRegistered.add(url); + } + } + + @Override + public void unregister(URL url) { + // 已销毁,跳过 + if (destroyed.get()){ + return; + } + // 移除出 `registered` 变量 + super.unregister(url); + // 移除出 `failedRegistered` `failedUnregistered` 变量 + failedRegistered.remove(url); + failedUnregistered.remove(url); + // 向注册中心发送取消注册请求 + try { + doUnregister(url); + } catch (Exception e) { + Throwable t = e; + + // 如果开启了启动时检测,则直接抛出异常 + boolean check = getUrl().getParameter(Constants.CHECK_KEY, true) + && url.getParameter(Constants.CHECK_KEY, true) + && !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol()); + boolean skipFailback = t instanceof SkipFailbackWrapperException; + if (check || skipFailback) { + if (skipFailback) { + t = t.getCause(); + } + throw new IllegalStateException("Failed to unregister " + url + " to registry " + getUrl().getAddress() + ", cause: " + t.getMessage(), t); + } else { + logger.error("Failed to uregister " + url + ", waiting for retry, cause: " + t.getMessage(), t); + } + + // 将失败的取消注册请求记录到 `failedUnregistered`,定时重试 + failedUnregistered.add(url); + } + } + + @Override + public void subscribe(URL url, NotifyListener listener) { + // 已销毁,跳过 + if (destroyed.get()){ + return; + } + // 移除出 `subscribed` 变量 + super.subscribe(url, listener); + // 移除出 `failedSubscribed` `failedUnsubscribed` `failedNotified` + removeFailedSubscribed(url, listener); + // 向注册中心发送订阅请求 + try { + doSubscribe(url, listener); + } catch (Exception e) { + Throwable t = e; + + // 如果有缓存的 URL 集合,进行通知。后续订阅成功后,会使用最新的 URL 集合,进行通知。 + List urls = getCacheUrls(url); + if (urls != null && !urls.isEmpty()) { + notify(url, listener, urls); + logger.error("Failed to subscribe " + url + ", Using cached list: " + urls + " from cache file: " + getUrl().getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/dubbo-registry-" + url.getHost() + ".cache") + ", cause: " + t.getMessage(), t); + } else { + // 如果开启了启动时检测,则直接抛出异常 + // 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); + boolean skipFailback = t instanceof SkipFailbackWrapperException; + if (check || skipFailback) { + if (skipFailback) { + t = t.getCause(); + } + throw new IllegalStateException("Failed to subscribe " + url + ", cause: " + t.getMessage(), t); + } else { + logger.error("Failed to subscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t); + } + } + + // 将失败的订阅请求记录到 `failedSubscribed`,定时重试 + // Record a failed registration request to a failed list, retry regularly + addFailedSubscribed(url, listener); + } + } + + @Override + public void unsubscribe(URL url, NotifyListener listener) { + // 已销毁,跳过 + if (destroyed.get()){ + return; + } + // 移除出 `unsubscribed` 变量 + super.unsubscribe(url, listener); + // 移除出 `failedSubscribed` `failedUnsubscribed` `failedNotified` + removeFailedSubscribed(url, listener); + // 向注册中心发送取消订阅请求 + try { + // Sending a canceling subscription request to the server side + doUnsubscribe(url, listener); + } 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); + boolean skipFailback = t instanceof SkipFailbackWrapperException; + if (check || skipFailback) { + if (skipFailback) { + t = t.getCause(); + } + throw new IllegalStateException("Failed to unsubscribe " + url + " to registry " + getUrl().getAddress() + ", cause: " + t.getMessage(), t); + } else { + logger.error("Failed to unsubscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t); + } + + // 将失败的订阅请求记录到 `failedUnsubscribed`,定时重试 + // Record a failed registration request to a failed list, retry regularly + Set listeners = failedUnsubscribed.get(url); + if (listeners == null) { + failedUnsubscribed.putIfAbsent(url, new ConcurrentHashSet()); + listeners = failedUnsubscribed.get(url); + } + listeners.add(listener); + } + } + + @Override + protected void notify(URL url, NotifyListener listener, List urls) { + if (url == null) { + throw new IllegalArgumentException("notify url == null"); + } + if (listener == null) { + throw new IllegalArgumentException("notify listener == null"); + } + // 通知监听器 + try { + doNotify(url, listener, urls); + } catch (Exception t) { + // 将失败的通知记录到 `failedNotified`,定时重试 + Map> listeners = failedNotified.get(url); + if (listeners == null) { + failedNotified.putIfAbsent(url, new ConcurrentHashMap>()); + listeners = failedNotified.get(url); + } + listeners.put(listener, urls); + logger.error("Failed to notify for subscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t); + } + } + + protected void doNotify(URL url, NotifyListener listener, List urls) { + super.notify(url, listener, urls); + } + + @Override + protected void recover() throws Exception { + // register 恢复注册,添加到 `failedRegistered` ,定时重试 + Set recoverRegistered = new HashSet(getRegistered()); + if (!recoverRegistered.isEmpty()) { + if (logger.isInfoEnabled()) { + logger.info("Recover register url " + recoverRegistered); + } + for (URL url : recoverRegistered) { + failedRegistered.add(url); + } + } + // subscribe 恢复订阅,添加到 `failedSubscribed` ,定时重试 + Map> recoverSubscribed = new HashMap>(getSubscribed()); + if (!recoverSubscribed.isEmpty()) { + if (logger.isInfoEnabled()) { + logger.info("Recover subscribe url " + recoverSubscribed.keySet()); + } + for (Map.Entry> entry : recoverSubscribed.entrySet()) { + URL url = entry.getKey(); + for (NotifyListener listener : entry.getValue()) { + addFailedSubscribed(url, listener); + } + } + } + } + + /** + * 重试 + */ + protected void retry() { + // 重试执行注册 + if (!failedRegistered.isEmpty()) { + Set failed = new HashSet(failedRegistered); // 避免并发冲突 + if (failed.size() > 0) { + if (logger.isInfoEnabled()) { + logger.info("Retry register " + failed); + } + try { + for (URL url : failed) { + try { + // 执行注册 + doRegister(url); + // 移除出 `failedRegistered` + failedRegistered.remove(url); + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry register " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry register " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + // 重试执行取消注册 + if (!failedUnregistered.isEmpty()) { + Set failed = new HashSet(failedUnregistered); // 避免并发冲突 + if (!failed.isEmpty()) { + if (logger.isInfoEnabled()) { + logger.info("Retry unregister " + failed); + } + try { + for (URL url : failed) { + try { + // 执行取消注册 + doUnregister(url); + // 移除出 `failedUnregistered` + failedUnregistered.remove(url); + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry unregister " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry unregister " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + // 重试执行注册 + if (!failedSubscribed.isEmpty()) { + Map> failed = new HashMap>(failedSubscribed); // 避免并发冲突 + for (Map.Entry> entry : new HashMap>(failed).entrySet()) { + if (entry.getValue() == null || entry.getValue().size() == 0) { + failed.remove(entry.getKey()); + } + } + if (failed.size() > 0) { + if (logger.isInfoEnabled()) { + logger.info("Retry subscribe " + failed); + } + try { + for (Map.Entry> entry : failed.entrySet()) { + URL url = entry.getKey(); + Set listeners = entry.getValue(); + for (NotifyListener listener : listeners) { + try { + // 执行注册 + doSubscribe(url, listener); + // 移除出监听器 + listeners.remove(listener); + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry subscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry subscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + // 重试执行取消注册 + if (!failedUnsubscribed.isEmpty()) { + Map> failed = new HashMap>(failedUnsubscribed); + for (Map.Entry> entry : new HashMap>(failed).entrySet()) { + if (entry.getValue() == null || entry.getValue().isEmpty()) { + failed.remove(entry.getKey()); + } + } + if (failed.size() > 0) { + if (logger.isInfoEnabled()) { + logger.info("Retry unsubscribe " + failed); + } + try { + for (Map.Entry> entry : failed.entrySet()) { + URL url = entry.getKey(); + Set listeners = entry.getValue(); + for (NotifyListener listener : listeners) { + try { + // 执行取消注册 + doUnsubscribe(url, listener); + // 移除出监听器 + listeners.remove(listener); + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry unsubscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry unsubscribe " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + // 重试执行通知监听器 + if (!failedNotified.isEmpty()) { + Map>> failed = new HashMap>>(failedNotified); + for (Map.Entry>> entry : new HashMap>>(failed).entrySet()) { + if (entry.getValue() == null || entry.getValue().size() == 0) { + failed.remove(entry.getKey()); + } + } + if (failed.size() > 0) { + if (logger.isInfoEnabled()) { + logger.info("Retry notify " + failed); + } + try { + for (Map> values : failed.values()) { + for (Map.Entry> entry : values.entrySet()) { + try { + NotifyListener listener = entry.getKey(); + List urls = entry.getValue(); + // 通知监听器 + listener.notify(urls); + // 移除出监听器 + values.remove(listener); + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry notify " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry + logger.warn("Failed to retry notify " + failed + ", waiting for again, cause: " + t.getMessage(), t); + } + } + } + } + + @Override + public void destroy() { + // 忽略,若已经销毁 + if (!canDestroy()) { + return; + } + // 调用父方法,取消注册和订阅 + super.destroy(); + // 销毁重试任务 + try { + retryFuture.cancel(true); + } catch (Throwable t) { + logger.warn(t.getMessage(), t); + } + } + + // TODO: 2017/8/30 to abstract this method + protected boolean canDestroy(){ + return destroyed.compareAndSet(false, true); + } + + // ==== Template method ==== + + protected abstract void doRegister(URL url); + + protected abstract void doUnregister(URL url); + + protected abstract void doSubscribe(URL url, NotifyListener listener); + + protected abstract void doUnsubscribe(URL url, NotifyListener listener); +} +``` + +### RegistryFactory 和 AbstractRegistryFactory +RegistryFactory接口 是 Registry的工厂接口,用来返回 Registry实例。该接口是一个可扩展接口,可以看到该接口上有个@SPI注解,并且默认值为dubbo,也就是默认扩展的是DubboRegistryFactory。AbstractRegistryFactory 则是实现了 RegistryFactory接口 的抽象类。其源码如下。 +```java +/** + * 注册中心工厂 + */ +@SPI("dubbo") +public interface RegistryFactory { + + /** + * 根据注册中心连接地址,获取注册中心实例 + *

+ * 连接注册中心需处理契约:
+ * 1. 当设置check=false时表示不检查连接,否则在连接不上时抛出异常。
+ * 2. 支持URL上的username:password权限认证。
+ * 3. 支持backup=10.20.153.10备选注册中心集群地址。
+ * 4. 支持file=registry.cache本地磁盘文件缓存。
+ * 5. 支持timeout=1000请求超时设置。
+ * 6. 支持session=60000会话超时或过期设置。
+ * + * @param url 注册中心地址,不允许为空 + * @return 注册中心引用,总不返回空 + */ + @Adaptive({"protocol"}) + Registry getRegistry(URL url); +} + +/** + * 注册中心抽象类 + */ +public abstract class AbstractRegistryFactory implements RegistryFactory { + + // Log output + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRegistryFactory.class); + + // The lock for the acquisition process of the registry + private static final ReentrantLock LOCK = new ReentrantLock(); + + /** + * Registry 集合 + */ + private static final Map REGISTRIES = new ConcurrentHashMap(); + + /** + * Get all registries + */ + public static Collection getRegistries() { + return Collections.unmodifiableCollection(REGISTRIES.values()); + } + + /** + * 销毁所有 Registry + */ + // TODO: 2017/8/30 to move somewhere else better + public static void destroyAll() { + if (LOGGER.isInfoEnabled()) { + LOGGER.info("Close all registries " + getRegistries()); + } + // 获得锁 + LOCK.lock(); + try { + // 销毁 + for (Registry registry : getRegistries()) { + try { + registry.destroy(); + } catch (Throwable e) { + LOGGER.error(e.getMessage(), e); + } + } + // 清空缓存 + REGISTRIES.clear(); + } finally { + // 释放锁 + LOCK.unlock(); + } + } + + /** + * 获得注册中心 Registry 对象 + * + * @param url 注册中心地址,不允许为空 + * @return Registry 对象 + */ + @Override + public Registry getRegistry(URL url) { + // 修改 URL + url = url.setPath(RegistryService.class.getName()) // + `path` + .addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName()) // + `parameters.interface` + .removeParameters(Constants.EXPORT_KEY, Constants.REFER_KEY); // - `export` + // 计算 key + String key = url.toServiceString(); + // 获得锁 + // Lock the registry access process to ensure a single instance of the registry + LOCK.lock(); + try { + // 从缓存中获得 Registry 对象 + Registry registry = REGISTRIES.get(key); + if (registry != null) { + return registry; + } + // 缓存不存在,进行创建 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(); + } + } + + /** + * 创建 Registry 对象 + * + * @param url 注册中心地址 + * @return Registry 对象 + */ + protected abstract Registry createRegistry(URL url); +} +``` +### NotifyListener 和 RegistryDirectory +最后我们来看一下 dubbo-registry-api 模块下的另一个比较重要的组件,NotifyListener接口 和 RegistryDirectory抽象类。NotifyListener接口 只有一个notify方法,通知监听器。当收到服务变更通知时触发。RegistryDirectory是注册中心服务,维护着所有可用的远程Invoker或者本地的Invoker,它的Invoker集合是从注册中心获取的,另外,它实现了NotifyListener接口。比如消费方要调用某远程服务,会向注册中心订阅这个服务的所有 服务提供方,在订阅 及 服务提供方数据有变动时,回调消费方的NotifyListener服务的notify方法,回调接口传入所有服务提供方的url地址然后将urls转化为invokers,也就是refer应用远程服务。源码如下。 +```java +/** + * 通知监听器 + */ +public interface NotifyListener { + + /** + * 当收到服务变更通知时触发。 + *

+ * 通知需处理契约:
+ * 1. 总是以服务接口和数据类型为维度全量通知,即不会通知一个服务的同类型的部分数据,用户不需要对比上一次通知结果。
+ * 2. 订阅时的第一次通知,必须是一个服务的所有类型数据的全量通知。
+ * 3. 中途变更时,允许不同类型的数据分开通知,比如:providers, consumers, routers, overrides,允许只通知其中一种类型,但该类型的数据必须是全量的,不是增量的。
+ * 4. 如果一种类型的数据为空,需通知一个empty协议并带category参数的标识性URL数据。
+ * 5. 通知者(即注册中心实现)需保证通知的顺序,比如:单线程推送,队列串行化,带版本对比。
+ * + * @param urls 已注册信息列表,总不为空,含义同{@link com.alibaba.dubbo.registry.RegistryService#lookup(URL)}的返回值。 + */ + void notify(List urls); +} + + +/** + * 基于注册中心的 Directory 实现类 + */ +public class RegistryDirectory extends AbstractDirectory implements NotifyListener { + + private static final Logger logger = LoggerFactory.getLogger(RegistryDirectory.class); + + // ========== Dubbo SPI Adaptive 对象 BEGIN ========== + + /** + * Cluster$Adaptive 对象 + */ + private static final Cluster cluster = ExtensionLoader.getExtensionLoader(Cluster.class).getAdaptiveExtension(); + /** + * RouterFactory$Adaptive 对象 + */ + private static final RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getAdaptiveExtension(); + /** + * ConfiguratorFactory$Adaptive 对象 + */ + private static final ConfiguratorFactory configuratorFactory = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class).getAdaptiveExtension(); + + // ========== 服务消费者相关 BEGIN ========== + + /** + * 服务类型,例如:com.alibaba.dubbo.demo.DemoService + */ + private final Class serviceType; // Initialization at construction time, assertion not null + /** + * Consumer URL 的配置项 Map + */ + private final Map queryMap; // Initialization at construction time, assertion not null + /** + * 服务方法数组 + */ + private final String[] serviceMethods; + /** + * 是否引用多分组 + * + * 服务分组:https://dubbo.gitbooks.io/dubbo-user-book/demos/service-group.html + */ + private final boolean multiGroup; + + // ========== 注册中心相关 BEGIN ========== + + /** + * 注册中心的 Protocol 对象 + */ + private Protocol protocol; // Initialization at the time of injection, the assertion is not null + /** + * 注册中心 + */ + private Registry registry; // Initialization at the time of injection, the assertion is not null + /** + * 注册中心的服务类,目前是 com.alibaba.dubbo.registry.RegistryService + * + * 通过 {@link #url} 的 {@link URL#getServiceKey()} 获得 + */ + private final String serviceKey; // Initialization at construction time, assertion not null + /** + * 是否禁止访问。 + * + * 有两种情况会导致: + * + * 1. 没有服务提供者 + * 2. 服务提供者被禁用 + */ + private volatile boolean forbidden = false; + + // ========== 配置规则相关 BEGIN ========== + + /** + * 原始的目录 URL + * + * 例如:zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&callbacks=1000&check=false&client=netty4&cluster=failback&dubbo=2.0.0&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello,callbackParam,save,update,say03,delete,say04,demo,say01,bye,say02,saves&payload=1000&pid=63400&qos.port=33333®ister.ip=192.168.16.23&sayHello.async=true&side=consumer&timeout=10000×tamp=1527056491064 + */ + private final URL directoryUrl; // Initialization at construction time, assertion not null, and always assign non null value + /** + * 覆写的目录 URL ,结合配置规则 + */ + private volatile URL overrideDirectoryUrl; // Initialization at construction time, assertion not null, and always assign non null value + /** + * 配置规则数组 + * + * override rules + * Priority: override>-D>consumer>provider + * Rule one: for a certain provider + * Rule two: for all providers <* ,timeout=5000> + */ + private volatile List configurators; // The initial value is null and the midway may be assigned to null, please use the local variable reference + + // ========== 服务提供者相关 BEGIN ========== + + /** + * [url]与[服务提供者 Invoker 集合]的映射缓存 + */ + // Map cache service url to invoker mapping. + private volatile Map> urlInvokerMap; // The initial value is null and the midway may be assigned to null, please use the local variable reference + /** + * [方法名]与[服务提供者 Invoker 集合]的映射缓存 + */ + // Map cache service method to invokers mapping. + private volatile Map>> methodInvokerMap; // The initial value is null and the midway may be assigned to null, please use the local variable reference + /** + * [服务提供者 Invoker 集合]缓存 + */ + // Set cache invokeUrls to invokers mapping. + private volatile Set cachedInvokerUrls; // The initial value is null and the midway may be assigned to null, please use the local variable reference + + public RegistryDirectory(Class serviceType, URL url) { + super(url); + if (serviceType == null) { + throw new IllegalArgumentException("service type is null."); + } + if (url.getServiceKey() == null || url.getServiceKey().length() == 0) { + throw new IllegalArgumentException("registry serviceKey is null."); + } + this.serviceType = serviceType; + this.serviceKey = url.getServiceKey(); + // 获得 queryMap + this.queryMap = StringUtils.parseQueryString(url.getParameterAndDecoded(Constants.REFER_KEY)); + // 获得 overrideDirectoryUrl 和 directoryUrl + this.overrideDirectoryUrl = this.directoryUrl = url.setPath(url.getServiceInterface()).clearParameters().addParameters(queryMap).removeParameter(Constants.MONITOR_KEY); + // 初始化 multiGroup + String group = directoryUrl.getParameter(Constants.GROUP_KEY, ""); + this.multiGroup = group != null && ("*".equals(group) || group.contains(",")); + // 初始化 serviceMethods + String methods = queryMap.get(Constants.METHODS_KEY); + this.serviceMethods = methods == null ? null : Constants.COMMA_SPLIT_PATTERN.split(methods); + } + + /** + * 将overrideURL 转换为 map,供重新 refer 时使用. + * 每次下发全部规则,全部重新组装计算 + * + * @param urls 契约: + *
1.override://0.0.0.0/...(或override://ip:port...?anyhost=true)¶1=value1...表示全局规则(对所有的提供者全部生效) + *
2.override://ip:port...?anyhost=false 特例规则(只针对某个提供者生效) + *
3.不支持override://规则... 需要注册中心自行计算. + *
4.不带参数的override://0.0.0.0/ 表示清除override + * + * @return Configurator 集合 + */ + public static List toConfigurators(List urls) { + // 忽略,若配置规则 URL 集合为空 + if (urls == null || urls.isEmpty()) { + return Collections.emptyList(); + } + + // 创建 Configurator 集合 + List configurators = new ArrayList(urls.size()); + for (URL url : urls) { + // 若协议为 `empty://` ,意味着清空所有配置规则,因此返回空 Configurator 集合 + if (Constants.EMPTY_PROTOCOL.equals(url.getProtocol())) { + configurators.clear(); + break; + } + // 对应第 4 条契约,不带参数的 override://0.0.0.0/ 表示清除 override + Map override = new HashMap(url.getParameters()); + // The anyhost parameter of override may be added automatically, it can't change the judgement of changing url + // override 上的 anyhost 可能是自动添加的,不能影响改变url判断 + override.remove(Constants.ANYHOST_KEY); + if (override.size() == 0) { + configurators.clear(); + continue; + } + // 获得 Configurator 对象,并添加到 `configurators` 中 + configurators.add(configuratorFactory.getConfigurator(url)); + } + // 排序 + Collections.sort(configurators); + return configurators; + } + + public void setProtocol(Protocol protocol) { + this.protocol = protocol; + } + + public void setRegistry(Registry registry) { + this.registry = registry; + } + + /** + * 发起订阅 + * + * @param url 消费者 URL + */ + public void subscribe(URL url) { + // 设置消费者 URL + setConsumerUrl(url); + // 向注册中心,发起订阅 + registry.subscribe(url, this); + } + + @Override + public void destroy() { + if (isDestroyed()) { + return; + } + // 取消订阅 + // unsubscribe. + try { + if (getConsumerUrl() != null && registry != null && registry.isAvailable()) { + registry.unsubscribe(getConsumerUrl(), this); + } + } catch (Throwable t) { + logger.warn("unexpeced error when unsubscribe service " + serviceKey + "from registry" + registry.getUrl(), t); + } + // 标记已经销毁 + super.destroy(); // must be executed after unsubscribing + // 销毁所有 Invoker + try { + destroyAllInvokers(); + } catch (Throwable t) { + logger.warn("Failed to destroy service " + serviceKey, t); + } + } + + @Override + public synchronized void notify(List urls) { + // 根据 URL 的分类或协议,分组成三个集合 。 + List invokerUrls = new ArrayList(); // 服务提供者 URL 集合 + List routerUrls = new ArrayList(); + List configuratorUrls = new ArrayList(); + for (URL url : urls) { + String protocol = url.getProtocol(); + String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); + if (Constants.ROUTERS_CATEGORY.equals(category) || Constants.ROUTE_PROTOCOL.equals(protocol)) { + routerUrls.add(url); + } else if (Constants.CONFIGURATORS_CATEGORY.equals(category) || Constants.OVERRIDE_PROTOCOL.equals(protocol)) { + configuratorUrls.add(url); + } else if (Constants.PROVIDERS_CATEGORY.equals(category)) { + invokerUrls.add(url); + } else { + logger.warn("Unsupported category " + category + " in notified url: " + url + " from registry " + getUrl().getAddress() + " to consumer " + NetUtils.getLocalHost()); + } + } + // 处理配置规则 URL 集合 + // configurators + if (!configuratorUrls.isEmpty()) { + this.configurators = toConfigurators(configuratorUrls); + } + // 处理路由规则 URL 集合 + // routers + if (!routerUrls.isEmpty()) { + List routers = toRouters(routerUrls); + if (routers != null) { // null - do nothing + setRouters(routers); + } + } + // 合并配置规则,到 `directoryUrl` 中,形成 `overrideDirectoryUrl` 变量。 + List localConfigurators = this.configurators; // local reference + // merge override parameters + this.overrideDirectoryUrl = directoryUrl; + if (localConfigurators != null && !localConfigurators.isEmpty()) { + for (Configurator configurator : localConfigurators) { + this.overrideDirectoryUrl = configurator.configure(overrideDirectoryUrl); + } + } + // 处理服务提供者 URL 集合 + // providers + refreshInvoker(invokerUrls); + } + + /** + * 根据invokerURL列表转换为invoker列表。转换规则如下: + * + * 1.如果url已经被转换为invoker,则不在重新引用,直接从缓存中获取,注意如果url中任何一个参数变更也会重新引用 + * 2.如果传入的invoker列表不为空,则表示最新的invoker列表 + * 3.如果传入的invokerUrl列表是空,则表示只是下发的override规则或route规则,需要重新交叉对比,决定是否需要重新引用。 + * + * @param invokerUrls 传入的参数不能为null + */ + // TODO: 2017/8/31 FIXME The thread pool should be used to refresh the address, otherwise the task may be accumulated. + private void refreshInvoker(List invokerUrls) { + if (invokerUrls != null && invokerUrls.size() == 1 && invokerUrls.get(0) != null + && Constants.EMPTY_PROTOCOL.equals(invokerUrls.get(0).getProtocol())) { + // 设置禁止访问 + this.forbidden = true; // Forbid to access + // methodInvokerMap 置空 + this.methodInvokerMap = null; // Set the method invoker map to null + // 销毁所有 Invoker 集合 + destroyAllInvokers(); // Close all invokers + } else { + // 设置允许访问 + this.forbidden = false; // Allow to access + // 引用老的 urlInvokerMap + Map> oldUrlInvokerMap = this.urlInvokerMap; // local reference + // 传入的 invokerUrls 为空,说明是路由规则或配置规则发生改变,此时 invokerUrls 是空的,直接使用 cachedInvokerUrls 。 + if (invokerUrls.isEmpty() && this.cachedInvokerUrls != null) { + invokerUrls.addAll(this.cachedInvokerUrls); + // 传入的 invokerUrls 非空,更新 cachedInvokerUrls 。 + } else { + this.cachedInvokerUrls = new HashSet(); + this.cachedInvokerUrls.addAll(invokerUrls); //Cached invoker urls, convenient for comparison //缓存invokerUrls列表,便于交叉对比 + } + // 忽略,若无 invokerUrls + if (invokerUrls.isEmpty()) { + return; + } + // 将传入的 invokerUrls ,转成新的 urlInvokerMap + Map> newUrlInvokerMap = toInvokers(invokerUrls);// Translate url list to Invoker map + // 转换出新的 methodInvokerMap + Map>> newMethodInvokerMap = toMethodInvokers(newUrlInvokerMap); // Change method name to map Invoker Map + // state change + // If the calculation is wrong, it is not processed. 如果计算错误,则不进行处理. + if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0) { + logger.error(new IllegalStateException("urls to invokers error .invokerUrls.size :" + invokerUrls.size() + ", invoker.size :0. urls :" + invokerUrls.toString())); + return; + } + // 若服务引用多 group ,则按照 method + group 聚合 Invoker 集合 + this.methodInvokerMap = multiGroup ? toMergeMethodInvokerMap(newMethodInvokerMap) : newMethodInvokerMap; + this.urlInvokerMap = newUrlInvokerMap; + // 销毁不再使用的 Invoker 集合 + try { + destroyUnusedInvokers(oldUrlInvokerMap, newUrlInvokerMap); // Close the unused Invoker + } catch (Exception e) { + logger.warn("destroyUnusedInvokers error. ", e); + } + } + } + + /** + * 若服务引用多 group ,则按照 method + group 聚合 Invoker 集合 + */ + private Map>> toMergeMethodInvokerMap(Map>> methodMap) { + Map>> result = new HashMap>>(); + // 循环方法,按照 method + group 聚合 Invoker 集合 + for (Map.Entry>> entry : methodMap.entrySet()) { + String method = entry.getKey(); + List> invokers = entry.getValue(); + // 按照 Group 聚合 Invoker 集合的结果。其中,KEY:group VALUE:Invoker 集合。 + Map>> groupMap = new HashMap>>(); + // 循环 Invoker 集合,按照 group 聚合 Invoker 集合 + for (Invoker invoker : invokers) { + String group = invoker.getUrl().getParameter(Constants.GROUP_KEY, ""); + List> groupInvokers = groupMap.get(group); + if (groupInvokers == null) { + groupInvokers = new ArrayList>(); + groupMap.put(group, groupInvokers); + } + groupInvokers.add(invoker); + } + // 大小为 1,使用第一个 + if (groupMap.size() == 1) { + result.put(method, groupMap.values().iterator().next()); + // 大于 1,将每个 Group 的 Invoker 集合,创建成 Cluster Invoker 对象。 + } else if (groupMap.size() > 1) { + List> groupInvokers = new ArrayList>(); + for (List> groupList : groupMap.values()) { + groupInvokers.add(cluster.join(new StaticDirectory(groupList))); + } + result.put(method, groupInvokers); + // 大小为 0 ,使用原有值 + } else { + result.put(method, invokers); + } + } + return result; + } + + /** + * @param urls + * @return null : no routers ,do nothing + * else :routers list + */ + private List toRouters(List urls) { + List routers = new ArrayList(); + if (urls == null || urls.isEmpty()) { + return routers; + } + for (URL url : urls) { + // 忽略,若是 "empty://" 。一般情况下,所有路由规则被删除时,有且仅有一条协议为 "empty://" 的路由规则 URL + if (Constants.EMPTY_PROTOCOL.equals(url.getProtocol())) { + continue; + } + // 获得 "router" + String routerType = url.getParameter(Constants.ROUTER_KEY); + if (routerType != null && routerType.length() > 0) { + url = url.setProtocol(routerType); + } + try { + // 创建 Router 对象 + Router router = routerFactory.getRouter(url); + // 添加到返回结果 + if (!routers.contains(router)) { + routers.add(router); + } + } catch (Throwable t) { + logger.error("convert router url to router error, url: " + url, t); + } + } + return routers; + } + + /** + * 将服务提供者 URL 集合,转成 Invoker 集合。若该服务提供者 URL 已经转换,则直接复用,不重新引用。 + * + * @param urls URL 集合 + * @return invokers + */ + private Map> toInvokers(List urls) { + // 新的 `newUrlInvokerMap` + Map> newUrlInvokerMap = new HashMap>(); + // 若为空,直接返回 + if (urls == null || urls.isEmpty()) { + return newUrlInvokerMap; + } + // 已初始化的服务器提供 URL 集合 + Set keys = new HashSet(); + // 获得引用服务的协议 + String queryProtocols = this.queryMap.get(Constants.PROTOCOL_KEY); + // 循环服务提供者 URL 集合,转成 Invoker 集合 + for (URL providerUrl : urls) { + // If protocol is configured at the reference side, only the matching protocol is selected + // 如果 reference 端配置了 protocol ,则只选择匹配的 protocol + if (queryProtocols != null && queryProtocols.length() > 0) { + boolean accept = false; + String[] acceptProtocols = queryProtocols.split(","); // 可配置多个协议 + for (String acceptProtocol : acceptProtocols) { + if (providerUrl.getProtocol().equals(acceptProtocol)) { + accept = true; + break; + } + } + if (!accept) { + continue; + } + } + // 忽略,若为 `empty://` 协议 + if (Constants.EMPTY_PROTOCOL.equals(providerUrl.getProtocol())) { + continue; + } + // 忽略,若应用程序不支持该协议 + if (!ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) { + logger.error(new IllegalStateException("Unsupported protocol " + providerUrl.getProtocol() + " in notified url: " + providerUrl + " from registry " + getUrl().getAddress() + " to consumer " + NetUtils.getLocalHost() + + ", supported protocol: " + ExtensionLoader.getExtensionLoader(Protocol.class).getSupportedExtensions())); + continue; + } + // 合并 URL 参数 + URL url = mergeUrl(providerUrl); + // 忽略,若已经初始化 + String key = url.toFullString(); // The parameter urls are sorted + if (keys.contains(key)) { // Repeated url + continue; + } + // 添加到 `keys` 中 + keys.add(key); + // Cache key is url that does not merge with consumer side parameters, regardless of how the consumer combines parameters, if the server url changes, then refer again + // 如果服务端 URL 发生变化,则重新 refer 引用 + Map> localUrlInvokerMap = this.urlInvokerMap; // local reference + Invoker invoker = localUrlInvokerMap == null ? null : localUrlInvokerMap.get(key); + if (invoker == null) { // Not in the cache, refer again 未在缓存中,重新引用 + try { + // 判断是否开启 + boolean enabled; + if (url.hasParameter(Constants.DISABLED_KEY)) { + enabled = !url.getParameter(Constants.DISABLED_KEY, false); + } else { + enabled = url.getParameter(Constants.ENABLED_KEY, true); + } + // 若开启,创建 Invoker 对象 + if (enabled) { + // 注意,引用服务 + invoker = new InvokerDelegate(protocol.refer(serviceType, url), url, providerUrl); + } + } catch (Throwable t) { + logger.error("Failed to refer invoker for interface:" + serviceType + ",url:(" + url + ")" + t.getMessage(), t); + } + // 添加到 newUrlInvokerMap 中 + if (invoker != null) { // Put new invoker in cache + newUrlInvokerMap.put(key, invoker); + } + } else { // 在缓存中,直接使用缓存的 Invoker 对象,添加到 newUrlInvokerMap 中 + newUrlInvokerMap.put(key, invoker); + } + } + // 清空 keys + keys.clear(); + return newUrlInvokerMap; + } + + /** + * Merge url parameters. the order is: override > -D >Consumer > Provider + * + * 合并 URL 参数,优先级为配置规则 > 服务消费者配置 > 服务提供者配置 + * + * @param providerUrl 服务提供者 URL + * @return 合并后的 URL + */ + private URL mergeUrl(URL providerUrl) { + // 合并消费端参数 + providerUrl = ClusterUtils.mergeUrl(providerUrl, queryMap); // Merge the consumer side parameters + + // 合并配置规则 + List localConfigurators = this.configurators; // local reference + if (localConfigurators != null && !localConfigurators.isEmpty()) { + for (Configurator configurator : localConfigurators) { + providerUrl = configurator.configure(providerUrl); + } + } + + // 不检查连接是否成功,总是创建 Invoker !因为,启动检查,只有启动阶段需要。此时在检查,已经没必要了。 + providerUrl = providerUrl.addParameter(Constants.CHECK_KEY, String.valueOf(false)); // Do not check whether the connection is successful or not, always create Invoker! + + // The combination of directoryUrl and override is at the end of notify, which can't be handled here + // 仅合并提供者参数,因为 directoryUrl 与 override 合并是在 notify 的最后,这里不能够处理 + this.overrideDirectoryUrl = this.overrideDirectoryUrl.addParametersIfAbsent(providerUrl.getParameters()); // Merge the provider side parameters + + // 【忽略】因为是对 1.0 版本的兼容 + if ((providerUrl.getPath() == null || providerUrl.getPath().length() == 0) + && "dubbo".equals(providerUrl.getProtocol())) { // Compatible version 1.0 + //fix by tony.chenl DUBBO-44 + String path = directoryUrl.getParameter(Constants.INTERFACE_KEY); + if (path != null) { + int i = path.indexOf('/'); + if (i >= 0) { + path = path.substring(i + 1); + } + i = path.lastIndexOf(':'); + if (i >= 0) { + path = path.substring(0, i); + } + providerUrl = providerUrl.setPath(path); + } + } + + // 返回服务提供者 URL + return providerUrl; + } + + private List> route(List> invokers, String method) { + // 创建 Invocation 对象 + Invocation invocation = new RpcInvocation(method, new Class[0], new Object[0]); + // 获得 Router 数组 + List routers = getRouters(); + // 根据路由规则,筛选 Invoker 集合 + if (routers != null) { + for (Router router : routers) { + if (router.getUrl() != null) { + invokers = router.route(invokers, getConsumerUrl(), invocation); + } + } + } + return invokers; + } + + /** + * 将invokers列表转成与方法的映射关系 + * + * @param invokersMap Invoker列表 + * @return Invoker与方法的映射关系 + */ + private Map>> toMethodInvokers(Map> invokersMap) { + // 创建新的 `methodInvokerMap` + Map>> newMethodInvokerMap = new HashMap>>(); + // 创建 Invoker 集合 + List> invokersList = new ArrayList>(); + // According to the methods classification declared by the provider URL, the methods is compatible with the registry to execute the filtered methods + // 按服务提供者 URL 所声明的 methods 分类,兼容注册中心执行路由过滤掉的 methods + if (invokersMap != null && invokersMap.size() > 0) { + // 循环每个服务提供者 Invoker + for (Invoker invoker : invokersMap.values()) { + String parameter = invoker.getUrl().getParameter(Constants.METHODS_KEY); // methods + if (parameter != null && parameter.length() > 0) { + String[] methods = Constants.COMMA_SPLIT_PATTERN.split(parameter); + if (methods != null && methods.length > 0) { + // 循环每个方法,按照方法名为维度,聚合到 `methodInvokerMap` 中 + for (String method : methods) { + if (method != null && method.length() > 0 && !Constants.ANY_VALUE.equals(method)) { // 当服务提供者的方法为 "*" ,代表泛化调用 + List> methodInvokers = newMethodInvokerMap.get(method); + if (methodInvokers == null) { + methodInvokers = new ArrayList>(); + newMethodInvokerMap.put(method, methodInvokers); + } + methodInvokers.add(invoker); + } + } + } + } + // 添加到 `invokersList` 中 + invokersList.add(invoker); + } + } + // 路由全 `invokersList` ,匹配合适的 Invoker 集合 + List> newInvokersList = route(invokersList, null); + // 添加 `newInvokersList` 到 `newMethodInvokerMap` 中,表示该服务提供者的全量 Invoker 集合 + newMethodInvokerMap.put(Constants.ANY_VALUE, newInvokersList); + // 循环,基于每个方法路由,匹配合适的 Invoker 集合 + if (serviceMethods != null && serviceMethods.length > 0) { + for (String method : serviceMethods) { + List> methodInvokers = newMethodInvokerMap.get(method); + if (methodInvokers == null || methodInvokers.isEmpty()) { + methodInvokers = newInvokersList; + } + newMethodInvokerMap.put(method, route(methodInvokers, method)); + } + } + // 循环排序每个方法的 Invoker 集合,并设置为不可变 + // sort and unmodifiable + for (String method : new HashSet(newMethodInvokerMap.keySet())) { + List> methodInvokers = newMethodInvokerMap.get(method); + Collections.sort(methodInvokers, InvokerComparator.getComparator()); + newMethodInvokerMap.put(method, Collections.unmodifiableList(methodInvokers)); + } + return Collections.unmodifiableMap(newMethodInvokerMap); + } + + /** + * Close all invokers + */ + private void destroyAllInvokers() { + Map> localUrlInvokerMap = this.urlInvokerMap; // local reference 本地引用,避免并发问题 + if (localUrlInvokerMap != null) { + // 循环 urlInvokerMap ,销毁所有服务提供者 Invoker + for (Invoker invoker : new ArrayList>(localUrlInvokerMap.values())) { + try { + invoker.destroy(); + } catch (Throwable t) { + logger.warn("Failed to destroy service " + serviceKey + " to provider " + invoker.getUrl(), t); + } + } + // urlInvokerMap 清空 + localUrlInvokerMap.clear(); + } + // methodInvokerMap 置空 + methodInvokerMap = null; + } + + /** + * Check whether the invoker in the cache needs to be destroyed + * If set attribute of url: refer.autodestroy=false, the invokers will only increase without decreasing,there may be a refer leak + * + * @param oldUrlInvokerMap + * @param newUrlInvokerMap + */ + private void destroyUnusedInvokers(Map> oldUrlInvokerMap, Map> newUrlInvokerMap) { + // 防御性编程,目前不存在这个情况 + if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0) { + // 销毁所有服务提供者 Invoker + destroyAllInvokers(); + return; + } + // check deleted invoker + // 对比新老集合,计算需要销毁的 Invoker 集合 + List deleted = null; + if (oldUrlInvokerMap != null) { + Collection> newInvokers = newUrlInvokerMap.values(); + for (Map.Entry> entry : oldUrlInvokerMap.entrySet()) { + // 若不存在,添加到 `deleted` 中 + if (!newInvokers.contains(entry.getValue())) { + if (deleted == null) { + deleted = new ArrayList(); + } + deleted.add(entry.getKey()); + } + } + } + + // 若有需要销毁的 Invoker ,则进行销毁 + if (deleted != null) { + for (String url : deleted) { + if (url != null) { + // 移除出 `urlInvokerMap` + Invoker invoker = oldUrlInvokerMap.remove(url); + if (invoker != null) { + try { + // 销毁 Invoker + invoker.destroy(); + if (logger.isDebugEnabled()) { + logger.debug("destroy invoker[" + invoker.getUrl() + "] success. "); + } + } catch (Exception e) { + logger.warn("destroy invoker[" + invoker.getUrl() + "] failed. " + e.getMessage(), e); + } + } + } + } + } + } + + @Override + public List> doList(Invocation invocation) { + if (forbidden) { + // 1. No service provider 2. Service providers are disabled + throw new RpcException(RpcException.FORBIDDEN_EXCEPTION, + "No provider available from registry " + getUrl().getAddress() + " for service " + getConsumerUrl().getServiceKey() + " on consumer " + NetUtils.getLocalHost() + + " use dubbo version " + Version.getVersion() + ", please check status of providers(disabled, not registered or in blacklist)."); + } + List> invokers = null; + Map>> localMethodInvokerMap = this.methodInvokerMap; // local reference + // 获得 Invoker 集合 + if (localMethodInvokerMap != null && localMethodInvokerMap.size() > 0) { + // 获得方法名、方法参数 + String methodName = RpcUtils.getMethodName(invocation); + Object[] args = RpcUtils.getArguments(invocation); + // 【第一】可根据第一个参数枚举路由 + if (args != null && args.length > 0 && args[0] != null + && (args[0] instanceof String || args[0].getClass().isEnum())) { +// invokers = localMethodInvokerMap.get(methodName + "." + args[0]); // The routing can be enumerated according to the first parameter + invokers = localMethodInvokerMap.get(methodName + args[0]); // The routing can be enumerated according to the first parameter + } + // 【第二】根据方法名获得 Invoker 集合 + if (invokers == null) { + invokers = localMethodInvokerMap.get(methodName); + } + // 【第三】使用全量 Invoker 集合。例如,`#$echo(name)` ,回声方法 + if (invokers == null) { + invokers = localMethodInvokerMap.get(Constants.ANY_VALUE); + } + // 【第四】使用 `methodInvokerMap` 第一个 Invoker 集合。防御性编程。 + if (invokers == null) { + Iterator>> iterator = localMethodInvokerMap.values().iterator(); + if (iterator.hasNext()) { + invokers = iterator.next(); + } + } + } + return invokers == null ? new ArrayList>(0) : invokers; + } + + @Override + public Class getInterface() { + return serviceType; + } + + @Override + public URL getUrl() { + return this.overrideDirectoryUrl; + } + + @Override + public boolean isAvailable() { + // 若已销毁,返回不可用 + if (isDestroyed()) { + return false; + } + // 任意一个 Invoker 可用,则返回可用 + Map> localUrlInvokerMap = urlInvokerMap; + if (localUrlInvokerMap != null && localUrlInvokerMap.size() > 0) { + for (Invoker invoker : new ArrayList>(localUrlInvokerMap.values())) { + if (invoker.isAvailable()) { + return true; + } + } + } + return false; + } + + /** + * Haomin: added for test purpose + */ + public Map> getUrlInvokerMap() { + return urlInvokerMap; + } + + /** + * Haomin: added for test purpose + */ + public Map>> getMethodInvokerMap() { + return methodInvokerMap; + } + + /** + * Invoker 排序器,根据 URL 升序 + */ + private static class InvokerComparator implements Comparator> { + + /** + * 单例 + */ + private static final InvokerComparator comparator = new InvokerComparator(); + + private InvokerComparator() { + } + + public static InvokerComparator getComparator() { + return comparator; + } + + @Override + public int compare(Invoker o1, Invoker o2) { + return o1.getUrl().toString().compareTo(o2.getUrl().toString()); + } + + } + + /** + * + * Invoker 代理类,主要用于存储注册中心下发的 url 地址,用于重新重新 refer 时能够根据 providerURL queryMap overrideMap 重新组装 + * + * @param + */ + private static class InvokerDelegate extends InvokerWrapper { + + /** + * 服务提供者 URL + * + * 未经过配置合并 + */ + private URL providerUrl; + + public InvokerDelegate(Invoker invoker, URL url, URL providerUrl) { + super(invoker, url); + this.providerUrl = providerUrl; + } + + public URL getProviderUrl() { + return providerUrl; + } + } +} +``` \ No newline at end of file diff --git a/images/Dubbo/Dubbo原理图.png b/images/Dubbo/Dubbo原理图.png new file mode 100644 index 0000000000000000000000000000000000000000..c3c91a1fdfbea3d5c5998e66358c3b50151afae6 GIT binary patch literal 71278 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 W%1vFP^+2%rV6$!QZ7y25ZTlZ&CS;TV literal 0 HcmV?d00001 diff --git a/images/Dubbo/RegistryFactory组件类图.png b/images/Dubbo/RegistryFactory组件类图.png new file mode 100644 index 0000000000000000000000000000000000000000..0890d7a6b6b374453eadc07f4bdc4025b9513c57 GIT binary patch literal 49134 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 Pygoa&I@;c0`JVb0$SYlB literal 0 HcmV?d00001 diff --git a/images/Dubbo/Registry组件类图.png b/images/Dubbo/Registry组件类图.png new file mode 100644 index 0000000000000000000000000000000000000000..68c950dcb77346f421b7339fe3291b955d976ca8 GIT binary patch literal 66450 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%0Aq< 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 literal 0 HcmV?d00001 diff --git a/images/Dubbo/dubbo-registry模块结构图.png b/images/Dubbo/dubbo-registry模块结构图.png new file mode 100644 index 0000000000000000000000000000000000000000..1178edbc44967720ca6064623baff8e69dc55ddd GIT binary patch literal 21661 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 Vl*}+(IiQO|j4mTCRq8v&{tKE?)9(NP literal 0 HcmV?d00001