Dubbo源码-09-RegistryFactory

作用

远程配置中心的实现

  • ZookeeperRegistryFactory 实现zookeeper的远程配置中心,获取zk的读取zkClient

一 接口声明

@SPI("dubbo")
public interface RegistryFactory {

    /**
     * Connect to the registry
     * <p>
     * Connecting the registry needs to support the contract: <br>
     * 1. When the check=false is set, the connection is not checked, otherwise the exception is thrown when disconnection <br>
     * 2. Support username:password authority authentication on URL.<br>
     * 3. Support the backup=10.20.153.10 candidate registry cluster address.<br>
     * 4. Support file=registry.cache local disk file cache.<br>
     * 5. Support the timeout=1000 request timeout setting.<br>
     * 6. Support session=60000 session timeout or expiration settings.<br>
     *
     * @param url Registry address, is not allowed to be empty
     * @return Registry reference, never return empty value
     */
    @Adaptive({"protocol"})
    Registry getRegistry(URL url);

}

从注解就可以看出来,默认实现是dubbo,扩展点是URL中的协议protocol

二 类图

很明显在抽象类中定义了抽象方法,子类关注具体的getRegistry()的实现,而使用哪个子类实现取决于URL中的协议

三 抽象

// AbstractRegistryFactory.java
@Override
    public Registry getRegistry(URL url) {
        url = url.setPath(RegistryService.class.getName())
                .addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName())
                .removeParameters(Constants.EXPORT_KEY, Constants.REFER_KEY);
        /**
         * url
         *     - zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=native-provider&dubbo=2.0.2&interface=com.alibaba.dubbo.registry.RegistryService&pid=38892&qos.port=22222&timestamp=1669559112755
         * key
         *     - zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService
         */
        String key = url.toServiceStringWithoutResolving();
        // Lock the registry access process to ensure a single instance of the registry
        LOCK.lock();
        try {
            Registry registry = REGISTRIES.get(key);
            if (registry != null) {
                return registry;
            }
            registry = this.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();
        }
    }

三 实现

1 ZookeeperRegistryFactory

@Override
    public Registry createRegistry(URL url) {
        return new ZookeeperRegistry(url, zookeeperTransporter);
    }
// ZookeeperRegistry.java
public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter) {
        // zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=native-provider&dubbo=2.0.2&interface=com.alibaba.dubbo.registry.RegistryService&pid=39657&qos.port=22222&timestamp=1669560173930
        super(url);
        if (url.isAnyHost()) {
            throw new IllegalStateException("registry address == null");
        }
        String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT); // dubbo
        if (!group.startsWith(Constants.PATH_SEPARATOR)) {
            group = Constants.PATH_SEPARATOR + group;
        }
        this.root = group; // /dubbo
        /**
         * 创建zk的客户端 后续操作客户端对zk进行读写
         * 实现有2个
         *     - ZkclientZookeeperTransporter
         *     - CuratorZookeeperTransporter
         * 默认是CuratorZookeeperTransporter
         */
        zkClient = zookeeperTransporter.connect(url);
        // zk监听器
        zkClient.addStateListener(new StateListener() {
            @Override
            public void stateChanged(int state) {
                if (state == RECONNECTED) {
                    try {
                        recover();
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            }
        });
    }
// CuratorZookeeperTransporter.java
@Override
    public ZookeeperClient connect(URL url) {
        return new CuratorZookeeperClient(url);
    }
// CuratorZookeeperClient.java
public CuratorZookeeperClient(URL url) {
        super(url);
        try {
            int timeout = url.getParameter(Constants.TIMEOUT_KEY, 5000);
            CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
                    .connectString(url.getBackupAddress())
                    .retryPolicy(new RetryNTimes(1, 1000))
                    .connectionTimeoutMs(timeout);
            String authority = url.getAuthority();
            if (authority != null && authority.length() > 0) {
                builder = builder.authorization("digest", authority.getBytes());
            }
            client = builder.build();
            client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
                @Override
                public void stateChanged(CuratorFramework client, ConnectionState state) {
                    if (state == ConnectionState.LOST) {
                        CuratorZookeeperClient.this.stateChanged(StateListener.DISCONNECTED);
                    } else if (state == ConnectionState.CONNECTED) {
                        CuratorZookeeperClient.this.stateChanged(StateListener.CONNECTED);
                    } else if (state == ConnectionState.RECONNECTED) {
                        CuratorZookeeperClient.this.stateChanged(StateListener.RECONNECTED);
                    }
                }
            });
            client.start();
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
posted @ 2022-11-25 16:50  Bannirui  阅读(37)  评论(0编辑  收藏  举报