Dubbo源码解析:注册中心

在这里插入图片描述

介绍

dubbo注册中心的代码定义在dubbo-registry模块中,可以看到dubbo可以使用consul,redis,zookeeper来实现注册中心。default是基于内存实现的注册中心,multicast是基于广播实现的注册中心。

在这里插入图片描述

Registry继承了RegistryService接口,RegistryService接口定义了对注册中心的基本操作

public interface RegistryService {

    // 注册
    void register(URL url);

    // 注销
    void unregister(URL url);

    // 订阅
    void subscribe(URL url, NotifyListener listener);

    // 退订
    void unsubscribe(URL url, NotifyListener listener);

    // 查找服务地址
    List<URL> lookup(URL url);

}

继承关系如下图

在这里插入图片描述

AbstractRegistry对注册中心的内容进行了缓存,这样能保证当注册中心不可用的时候,还能正常提供服务

register和subscribe等操作比较简单,就是往缓存中添加删除服务,往缓存中添加删除对应的监听器。

FailbackRegistry增加了重试机制

注册中心是如何创建的?

注册中心的创建是通过工厂模式来实现的,每种注册中心的实现对应一种工厂类

在这里插入图片描述

@SPI("dubbo")
public interface RegistryFactory {

    @Adaptive({"protocol"})
    Registry getRegistry(URL url);

}

可以看到具体的工厂类实现都继承了AbstractRegistryFactory,来看一下AbstractRegistryFactory做了哪些操作?

public Registry getRegistry(URL url) {
    // 省略部分代码
    // 只有一个线程创建服务注册实例
    LOCK.lock();
    try {
        // 访问缓存
        Registry registry = REGISTRIES.get(key);
        if (registry != null) {
            return registry;
        }
        //create registry by spi/ioc
        // 是个抽象方法,子类来实现具体的创建过程
        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,子类来实现具体的创建过程

Zookeeper注册中心

成熟的注册中心框架,可用于生产环境

在这里插入图片描述

流程说明:

  1. 服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
  2. 服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址
  3. 监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址。

针对每个接口节点会存在如下4个子节点(接口节点及其子节点都是持久节点)

节点名作用子节点是否是持久节点
configuators存储override或者absent url,用于服务治理
consumers服务消费者url
providers服务提供者url
routers设置路由url,用于服务治理

consumers节点主要是为了做监控,其他三个节点都会设置监听器,发生改变时,会触发特定事件

ZookeeperRegistry对注册中心的操作都会交给ZookeeperClient。在2.7.x版本之前,dubbo支持zkclient和curator两种zookeeper客户端的实现,所以对zookeeper的操作又抽取出一套api出来,包括事件监听的接口。2.7.x版本只支持curator客户端

public interface ZookeeperClient {

    void create(String path, boolean ephemeral);

    void delete(String path);

    List<String> getChildren(String path);

    List<String> addChildListener(String path, ChildListener listener);

    void addDataListener(String path, DataListener listener);

    void addStateListener(StateListener listener);

}

ZookeeperClient包含了所有对注册中心的操作,并且定义了3种类型的监听器

  1. StateListener,监听连接状态
  2. ChildListener,监听获得一个节点的所有子节点(发生任何事件都重新获取一下)
  3. DataListener,监听本节点及其子节点的变化(节点增加,节点)

在这里插入图片描述

AbstractZookeeperClient主要对添加删除监听器进行并发控制。如果已经对某个路径添加了监听器就不再添加

CuratorZookeeperClient主要就是利用curaotr api对zookeeper进行操作的实现。其内部类CuratorWatcherImpl将curator中的事件转化为dubbo中的事件

参考博客

相关文章

在网络请求时,总会有各种异常情况出现,我们需要提前处理这...
作者:宇曾背景软件技术的发展历史,从单体的应用,逐渐演进...
hello,大家好呀,我是小楼。最近一个技术群有同学at我,问我...
 一个软件开发人员,工作到了一定的年限(一般是3、4年左右...
当一个服务调用另一个远程服务出现错误时的外观Dubbo提供了多...
最近在看阿里开源RPC框架Dubbo的源码,顺带梳理了一下其中用...