dubbo源码深度解读七之registery模块

来源:互联网 发布:java字符串时间转换 编辑:程序博客网 时间:2024/06/07 10:47

前言:dubbo-registry是注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。Dubbo的注册中心提供了多种实现,其实现是基于dubbo的spi的扩展机制的,我们也可以直接实现自己的注册中心。

(一)dubbo-registry-api
(1)RegistryFactory

@SPI("dubbo")public interface RegistryFactory {    /**     * 连接注册中心.     *      * 连接注册中心需处理契约:<br>     * 1. 当设置check=false时表示不检查连接,否则在连接不上时抛出异常。<br>     * 2. 支持URL上的username:password权限认证。<br>     * 3. 支持backup=10.20.153.10备选注册中心集群地址。<br>     * 4. 支持file=registry.cache本地磁盘文件缓存。<br>     * 5. 支持timeout=1000请求超时设置。<br>     * 6. 支持session=60000会话超时或过期设置。<br>     *      * @param url 注册中心地址,不允许为空     * @return 注册中心引用,总不返回空     */    @Adaptive({"protocol"})    Registry getRegistry(URL url);

类图如下:
这里写图片描述

RegistryFactory用来创建注册中心, 默认的注册中心是dubbo协议,由于阿里的注册中心并没有开源,dubbo协议注册中心只提供了一个简单实现。 开源dubbo的注册中心推荐使用zookeeper。这里我们主要去分析基于dubbo和zookeeper协议的注册中心实现及使用。

(2)RegistryService
类图如下:
这里写图片描述
代码如下:

public interface RegistryService {    /**     * 注册数据,比如:提供者地址,消费者地址,路由规则,覆盖规则,等数据。     *      * 注册需处理契约:<br>     * 1. 当URL设置了check=false时,注册失败后不报错,在后台定时重试,否则抛出异常。<br>     * 2. 当URL设置了dynamic=false参数,则需持久存储,否则,当注册者出现断电等情况异常退出时,需自动删除。<br>     * 3. 当URL设置了category=routers时,表示分类存储,缺省类别为providers,可按分类部分通知数据。<br>     * 4. 当注册中心重启,网络抖动,不能丢失数据,包括断线自动删除数据。<br>     * 5. 允许URI相同但参数不同的URL并存,不能覆盖。<br>     *      * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin     */    void register(URL url);    /**     * 取消注册.     *      * 取消注册需处理契约:<br>     * 1. 如果是dynamic=false的持久存储数据,找不到注册数据,则抛IllegalStateException,否则忽略。<br>     * 2. 按全URL匹配取消注册。<br>     *      * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin     */    void unregister(URL url);    /**     * 订阅符合条件的已注册数据,当有注册数据变更时自动推送.     *      * 订阅需处理契约:<br>     * 1. 当URL设置了check=false时,订阅失败后不报错,在后台定时重试。<br>     * 2. 当URL设置了category=routers,只通知指定分类的数据,多个分类用逗号分隔,并允许星号通配,表示订阅所有分类数据。<br>     * 3. 允许以interface,group,version,classifier作为条件查询,如:interface=com.alibaba.foo.BarService&version=1.0.0<br>     * 4. 并且查询条件允许星号通配,订阅所有接口的所有分组的所有版本,或:interface=*&group=*&version=*&classifier=*<br>     * 5. 当注册中心重启,网络抖动,需自动恢复订阅请求。<br>     * 6. 允许URI相同但参数不同的URL并存,不能覆盖。<br>     * 7. 必须阻塞订阅过程,等第一次通知完后再返回。<br>     *      * @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);    /**     * 取消订阅.     *      * 取消订阅需处理契约:<br>     * 1. 如果没有订阅,直接忽略。<br>     * 2. 按全URL匹配取消订阅。<br>     *      * @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);    /**     * 查询符合条件的已注册数据,与订阅的推模式相对应,这里为拉模式,只返回一次结果。     *      * @see com.alibaba.dubbo.registry.NotifyListener#notify(List)     * @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<URL>)}的参数。     */    List<URL> lookup(URL url);}

(二)注册中心之Zookeeper协议注册中心
服务的提供者和消费者在RegistryProtocol利用注册中心暴露(export)和引用(refer)服务的时候会根据配置利用Dubbo的SPI机制获取具体注册中心注册器
先查看ZookeeperRegistryFactory的代码

public class ZookeeperRegistryFactory extends AbstractRegistryFactory {    private ZookeeperTransporter zookeeperTransporter;    public void setZookeeperTransporter(ZookeeperTransporter zookeeperTransporter) {        this.zookeeperTransporter = zookeeperTransporter;    }    public Registry createRegistry(URL url) {        return new ZookeeperRegistry(url, zookeeperTransporter);    }}

这里创建zookeepr注册器ZookeeperRegistry,ZookeeperTransporter是操作zookeepr的客户端的工厂类,用来创建zookeeper客户端,这里客户端并不是zookeeper源代码的自带的,而是采用第三方工具包,主要来简化对zookeeper的操作,例如用zookeeper做注册中心需要对zookeeper节点添加watcher做反向推送,但是每次回调后节点的watcher都会被删除,这些客户会自动维护了这些watcher,在自动添加到节点上去。

接下来看ZookeeperRegistry的代码:

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() {            public void stateChanged(int state) {                if (state == RECONNECTED) {                    try {                        recover();                    } catch (Exception e) {                        logger.error(e.getMessage(), e);                    }                }            }        });    }

1.构造器利用客户端创建了对zookeeper的连接,并且添加了自动回复连接的监听器。

2.注册url就是利用客户端在服务器端创建url的节点,默认为临时节点,客户端与服务端断开,几点自动删除

3.取消注册的url,就是利用zookeeper客户端删除url节点

4.订阅url, 功能是服务消费端订阅服务提供方在zookeeper上注册地址.

5 取消订阅url, 只是去掉url上的注册的监听器

总结:这部分相对简单理解,几篇下来,已经对dubbo的各个模块有了基本的了解,接下来会进行整合,把思路连接起来,然后会分析一些好的设计模式等等,最后就会进行改造了,对于改造有什么想法的,欢迎私信我。

原创粉丝点击