前言
在Dubbo集群容错分析之前,要先有一个宏观的了解,集群容错源码分别是服务目录 Directory、服务路由 Router、集群 Cluster和负载均衡LoadBalance四个部分,这个在官网的博客中有简单的介绍,本篇就结合官网的介绍来简单介绍一下服务目录 Directory部分。
ps:以下所有的源码分析都是基于Dubbo2.6.6版本
Directory
1、简介
Directory也成为服务目录,我们知道,在服务消费者发送请求之前,我们需要知道它要往哪些服务提供者上发送请求,通过服务目录,服务消费者就能够获取到服务提供者的信息,就能够通过Netty进行相关函数的远程调用,所以也可以说,服务目录的功能和注册中心的功能是类似的,只不过它是将注册中心的每条服务提供者的信息封装成了一个Invoker对象, 在服务提供者发生变化的时候,服务目录也会随着注册中心动态更新。
官网上有这么一句话,Directory 代表多个 Invoker,可以把它看成 ListStaticDirectory],它是静态的,也就是不会动态变化的。另一个是RegistryDirectory,它是一个动态的服务目录。这边给出一张官网的继承体系图。

好像用的比较多的是RegistryDirectory,StaticDirectory用得比较少,主要用在服务对多注册中心的引用。
2、源码分析
AbstractDirectory源码分析
1 |
|
AbstractDirectory里面最重要的一个函数就是list函数,返回的是一个List<Invoker
1.
doList(invocation);方法:主要用来获得Invoker列表,它是由具体的子类实现的。2.
router.route(invokers, getConsumerUrl(), invocation);:进行服务路由。
好了,简单说完了AbstractDirectory,就来说说它的两个子类的实现。第一个StaticDirectory
StaticDirectory源码分析
1 | public StaticDirectory(List<Invoker<T>> invokers) { |
StaticDirectory的实现很简单,因为是静态的服务目录,所以在构造函数中就把invokers对象传进去了,后面也不能做动态的变化。doList()函数也就是很简单的把invokers对象返回出去。
RegistryDirectory源码分析
首先它实现了NotifyListener接口。当注册中心服务配置发生变化后,RegistryDirectory可收到与当前服务相关的变化,也就是它之所以能根据注册中心动态变化的根源所在。收到变更通知后,RegistryDirectory 可根据配置变更信息刷新 Invoker 列表。RegistryDirectory 中有几个比较重要的逻辑,第一是 Invoker 的列举逻辑,第二是接收服务配置变更的逻辑,第三是 Invoker 列表的刷新逻辑。接下来按顺序对这三块逻辑。
doList()方法
1 |
|
和静态服务目录的doList()方法不同,RegistryDirectory中的doList()方法就复杂多了。主要获取逻辑就是从methodInvokerMap对象中把Invoker读取出来就行了,读取逻辑是根据key = 方法名+参数的各种组合进行map的映射,也就是methodName和args对象。至于methodInvokerMap是啥,后面再分析一下,这边我猜测应该是所有在注册中心注册服务的服务提供者的方法和对应的List<Invoker
notify()方法
上面提到了它实现了NotifyListener接口,它是为了获取注册中心的变更通知,这边看一下它的具体实现
1 |
|
下面来看刷新函数
refreshInvoker(invokerUrls)
1 | private void refreshInvoker(List<URL> invokerUrls) { |
当注册中心有变化的时候,更新两个值,一个是methodInvokerMap,另一个是urlInvokerMap。上面在doList()中有对methodInvokerMap对象读的操作,这边是对methodInvokerMap对象写的操作。
这边涉及到的三个比较主要的函数这边就不分析了,具体的分析官方文档给出了详细的说明,我的理解是
1 | // 返回值对应<url, Invoker> |
这四步是紧密关联的,最终动态改变成员变量methodInvokerMap。