dubbo对注册中心的分装

Dubbo最主要干2个事情。第一个,对服务的导出和引入。第二个,维护注册中心的服务。对于第一个,尽量参考Dubbo官方文档,有详细解释。对于第二个,这边详细说说。

首先找到服务注册和引用的入口RegistryProtocol,这部分不清楚的话,可以参考文档Dubbo官方文档-服务导出

public void register(URL registryUrl, URL registedProviderUrl) {
   
  Registry registry = registryFactory.getRegistry(registryUrl);
  registry.register(registedProviderUrl);
}
@Override
public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
   
	// ----------------------此处省略一堆代码------------------------
  registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
	// ----------------------此处省略一堆代码------------------------
}

private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {
   
	// ----------------------此处省略一堆代码------------------------
  registry.register(subscribeUrl.addParameters(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY,
                                                 Constants.CHECK_KEY, String.valueOf(false)));
  // ----------------------此处省略一堆代码------------------------
}

上面省略了大量的代码,只是把关于registry的几个调用点贴出来了。可以看到有registersubscribe两个行为。然后看看RegistryService接口中,总共有多少行为。

public interface RegistryService {
   
		// 向注册中心注册url
    void register(URL url);
		// 从注册中心删除(卸载)url
    void unregister(URL url);
		// 向注册中心注册对某个目录的监听
    void subscribe(URL url, NotifyListener listener);
		// 从注册中心删除(卸载)对某个目录的监听
    void unsubscribe(URL url, NotifyListener listener);
		// 从注册中心查询服务
    List<URL> lookup(URL url);
}

RegistryService可以看到除了上面出现的2个行为,还有2个反向的。还有一个查询。很容易理解。把RegistryService中的5个行为抽象出来之后,就可以有很好的扩展性。可以适配rediszookeeper,数据库,或者开发者自定义实现方式。

注册过程分为2步

1.向注册中心发送注册(Register)请求(具体注册的内容和存储形式要看使用的是什么注册中心)

2.向注册中心发起订阅请求(订阅的具体内容,和订阅形式要看使用的是什么注册中心)

删除注册过程分为2步

1.向注册中心发送删除注册(UnRegister)请求

2.向注册中心发起取消订阅(Unsubscribe)请求

看下类结构图:

结构很清晰。Dubbo给出了4种实现。先从Zookeeper开始说。看下示意图。

zookeeper作为注册中心

服务启动并且注册完成后,每个服务都会在zookeeper上建立4个永久目录。可以从上图中看到。找到代码ZookeeperRegistry.toCategoriesPath。可以看到4个目录的建立是在这个地方设置的。

private String[] toCategoriesPath(URL url) {
   
// ----------------------此处省略一堆代码------------------------		
		categories = new String[]{
   Constants.PROVIDERS_CATEGORY, Constants.CONSUMERS_CATEGORY,
                Constants.ROUTERS_CATEGORY, Constants.CONFIGURATORS_CATEGORY};
// ----------------------此处省略一堆代码------------------------
}

其中configuratorsrouters并不常用,主要在配置和服务治理的时候才会用到。常用的是providersconsumers。如果一个服务有N个Provider,那在providers下面会产生N个子节点。同样的,如果一个服务有N个Consumer,那在consumers下面会产生N个子节点。关于子节点中对服务的描述会比较长,这边给出一个示意图,调试代码的可以直接登录到Zookeeper查看自己的服务情况。

注册过程是在zookeeper上建立目录并且把服务的描述信息写进去。除此之外还需要订阅它关注的服务。服务也就是目录(Dubbo把它抽象为Directory)。ProviderConsumer都有个自己关心的几个目录。

Provider只关心configurators,因为它不关心有多少Consumer,或者Consumer的路由策略。所以Provider会监视configurators

Consumer会关心configuratorsroutersproviders,它需要关心各个provider的动态,和自己的路由策略。所以Consumer会分别监视configuratorsroutersproviders

对于所监视的目录,只要children发生任何变化都会触发childChanged事件。然后做出相应处理。

比如:Consumer监视providers的动态,当/dubbo/com.xxx.XxxService/providers目录下减少服务时。会触发Consumer重新搜有这个目录下所有的服务,并且重新维护Consumer的服务列表(具体对服务列表的维护需要关注Dubbo Directory模块的代码),客户代码再次调用这个服务时,被删除的服务节点不会再收到服务请求。

Dubbo为了兼容多个zk客户端,还搞了一个ZookeeperTransprter层。官方给出了2种实现,分别是curatorzkClient。看下类图结构。

还是比较清晰的。看下ZookeeperTransporter的代码。

@SPI("curator")// 默认使用curator
public interface ZookeeperTransporter {
   

		// 建立连接,并且返回一个ZookeeperClient,后续的一些列对zookeeper的操作都需要以ZookeeperClient为委托。
    ZookeeperClient connect(URL url);
}

public class CuratorZookeeperTransporter implements ZookeeperTransporter {
   

  	// 与zookeeper建立连接的过程就是new CuratorZookeeperClient,连接的过程在构造方法中。
    @Override
    public ZookeeperClient connect(URL url) {
   
        return new CuratorZookeeperClient(url);
    }
}

Zookeeper建立连接的过程就是new CuratorZookeeperClient,连接的过程在构造方法中。

public class CuratorZookeeperClient extends 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值