1 org.apache.dubbo.common.Node接口
在 Dubbo 使用 Node 这个接口来抽象节点的概念。Node不仅可以表示 Provider 和 Consumer 节点,还可以表示注册中心节点。Node 接口中定义了几个非常基础的方法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/7ecea2a432e5495781b4fead7a8db57b.png#pic_center
public interface Node {
// 返回表示当前节点的 URL
URL getUrl();
// 检测当前节点是否可用
boolean isAvailable();
// 销毁当前节点并释放底层资源
void destroy();
}
2 org.apache.dubbo.registry.RegistryService
public interface RegistryService {
// 注册
void register(URL url);
// 取消注册/下线
void unregister(URL url);
// 订阅.订阅成功之后,当订阅的数据发生变化时,注册中心会主动通知第二个参数指定的 NotifyListener 对象
void subscribe(URL url, NotifyListener listener);
//取消订阅
void unsubscribe(URL url, NotifyListener listener);
// 查询符合条件的注册数据,它与 subscribe() 方法有一定的区别,subscribe() 方法采用的是 push 模式,lookup() 方法采用的是 pull 模式
List<URL> lookup(URL url);
}
3 org.apache.dubbo.registry.Registry
Registry 接口继承了 RegistryService 接口和 Node 接口,表示的就是一个拥有注册中心能力的节点,其中的 reExportRegister() 和 reExportUnregister() 方法都是委托给 RegistryService 接口中的相应方法:`
public interface Registry extends Node, RegistryService {
default int getDelay() {
return getUrl().getParameter(REGISTRY_DELAY_NOTIFICATION_KEY, DEFAULT_DELAY_NOTIFICATION_TIME);
}
default boolean isServiceDiscovery() {
return false;
}
default void reExportRegister(URL url) {
register(url);
}
default void reExportUnregister(URL url) {
unregister(url);
}
}
4 org.apache.dubbo.registry.RegistryFactory
RegistryFactory 接口是 Registry 的工厂接口,负责创建 Registry 对象,其中 @SPI 注解表示这是一个扩展需要加载org.apache.dubbo.registry.RegistryFactory文件中配置的RegistryFactory实现类,@Adaptive 注解表示会生成适配器类并根据 URL 参数中的 protocol 参数值选择相应的实现:
@SPI(scope = APPLICATION)
public interface RegistryFactory {
@Adaptive({"protocol"})
Registry getRegistry(URL url);
}
5 org.apache.dubbo.registry.RegistryFactoryWrapper
RegistryFactoryWrapper 是 RegistryFactory 接口的 Wrapper 类,它在底层 RegistryFactory 创建的 Registry 对象外层封装了一个 ListenerRegistryWrapper ,ListenerRegistryWrapper 中维护了一个 RegistryServiceListener 集合,会将 register()、subscribe() 等事件通知到 RegistryServiceListener 监听器。
public class RegistryFactoryWrapper implements RegistryFactory {
private RegistryFactory registryFactory;
public RegistryFactoryWrapper(RegistryFactory registryFactory) {
this.registryFactory = registryFactory;
}
@Override
public Registry getRegistry(URL url) {
return new ListenerRegistryWrapper(registryFactory.getRegistry(url),
Collections.unmodifiableList(url.getOrDefaultApplicationModel().getExtensionLoader(RegistryServiceListener.class)
.getActivateExtension(url, "registry.listeners")));
}
}
6 org.apache.dubbo.registry.support.AbstractRegistryFactory
AbstractRegistryFactory 是一个实现了 RegistryFactory 接口的抽象类,提供了规范 URL 的操作以及缓存 Registry 对象的公共能力。其中缓存 Registry 对象是使用RegistryManager实现,在RegistryManager中使用了 ConcurrentHashMap<String, Registry> 集合实现的(REGISTRIES 静态字段)。
7 org.apache.dubbo.registry.support.AbstractRegistry
AbstractRegistry 实现了 Registry 接口.
public abstract class AbstractRegistry implements Registry {
// URL address separator, used in file cache, service provider URL separation
private static final char URL_SEPARATOR = ' ';
// URL address separated regular expression for parsing the service provider URL list in the file cache
private static final String URL_SPLIT = "\\s+";
// Max times to retry to save properties to local cache file
private static final int MAX_RETRY_TIMES_SAVE_PROPERTIES = 3;
// Default interval in millisecond for saving properties to local cache file
private static final long DEFAULT_INTERVAL_SAVE_PROPERTIES = 500L;
// Log output
protected final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass());
// Local disk cache, where the special key value.registries records the list of registry centers, and the others are the list of notified service providers
// 本地的 Properties 文件缓存,properties 是加载到内存的 Properties 对象
private final Properties properties = new Properties();
// File cache timing writing
// 这是一个单线程的线程池,在一个 Provider 的注册数据发生变化的时候,会将该 Provider 的全量数据同步到 properties 字段和缓存文件中,
// 如果 syncSaveFile 配置为 false,就由该线程池异步完成文件写入
private final ScheduledExecutorService registryCacheExecutor;
// 注册数据的版本号,每次写入 file 文件时,都是全覆盖写入,而不是修改文件,所以需要版本控制,防止旧数据覆盖新数据
private final AtomicLong lastCacheChanged = new AtomicLong();
private final AtomicInteger savePropertiesRetryTimes = new AtomicInteger();
// 注册的 URL 集合
private final Set<URL> registered = new ConcurrentHashSet<>();
// 表示订阅 URL 的监听器集合,其中 Key 是被监听的 URL, Value 是相应的监听器集合
private final ConcurrentMap<URL, Set<NotifyListener>> subscribed = new ConcurrentHashMap<>();
// 该集合第一层 Key 是当前节点作为 Consumer 的一个 URL,表示的是该节点的某个 Consumer 角色(一个节点可以同时消费多个 Provider 节点);Value 是一个 Map 集合,
// 该 Map 集合的 Key 是 Provider URL 的分类(Category),例如 providers、routes、configurators 等,Value 就是相应分类下的 URL 集合
private final ConcurrentMap<URL, Map<String, List<URL>>> notified = new ConcurrentHashMap<>();
// Is it synchronized to save the file
private boolean syncSaveFile;
// URL 包含了创建该 Registry 对象的全部配置信息,是 AbstractRegistryFactory 修改后的产物
private URL registryUrl;
// Local disk cache file
private File file;
private final boolean localCacheEnabled;
protected RegistryManager registryManager;
protected ApplicationModel applicationModel;
......
}
8 org.apache.dubbo.registry.support.FailbackRegistry
该类继承了AbstractRegistry,覆盖了 AbstractRegistry 类中中 register/unregister/subscribe/unsubscribe/notify等核心方法.并提供了几个抽象方法与服务发现组件进行交互,他们分别是doRegister/doUnregister/doSubscribe/doUnsubscribe/doNotify
public abstract class FailbackRegistry extends AbstractRegistry {
/* retry task map */
// 注册失败的 URL 集合,其中 Key 是注册失败的 URL,Value 是对应的重试任务
private final ConcurrentMap<URL, FailedRegisteredTask> failedRegistered = new ConcurrentHashMap<>();
// 取消注册失败的 URL 集合,其中 Key 是取消注册失败的 URL,Value 是对应的重试任务
private final ConcurrentMap<URL, FailedUnregisteredTask> failedUnregistered = new ConcurrentHashMap<>();
// 阅失败 URL 集合,其中 Key 是订阅失败的 URL + Listener 集合,Value 是相应的重试任务
private final ConcurrentMap<Holder, FailedSubscribedTask> failedSubscribed = new ConcurrentHashMap<>();
// 取消订阅失败的 URL 集合,其中 Key 是取消订阅失败的 URL + Listener 集合,Value 是相应的重试任务
private final ConcurrentMap<Holder, FailedUnsubscribedTask> failedUnsubscribed = new ConcurrentHashMap<>();
/**
* The time in milliseconds the retryExecutor will wait
* 重试操作的时间间隔
*/
private final int retryPeriod;
// Timer for failure retry, regular check if there is a request for failure, and if there is, an unlimited retry
// 用于定时执行失败重试操作的时间轮
private final HashedWheelTimer retryTimer;
......
}
dubbo还提供了一个CacheableFailbackRegistry抽象类,CacheableFailbackRegistry继承了FailbackRegistry类,提供了多级缓存的能力.新增了 3 个缓存属性 stringAddress,stringParam 和 stringUrls,具体使用场景如下: