dubbo的zookeeper连接、创建节点、订阅

接着上一篇的dubbo的服务发布
上一篇讲完dubbo的远程服务发布之后,到了org.apache.dubbo.registry.integration.RegistryProtocol#exportdoLocalExport(originInvoker, providerUrl)调用之后,本篇看一下dubbo在远程服务发布完成之后对zookeeper的连接等操作
在这里插入图片描述

一. 创建zk连接

在这里插入图片描述
首先进入org.apache.dubbo.registry.integration.RegistryProtocol#getRegistry方法:
在这里插入图片描述
这里的registryFactory实际上还是SPI获取的一个动态代理类:RegistryFactory$Adaptive,那么这里既然是处理zk相关的,这里获取的肯定就是org.apache.dubbo.registry.zookeeper.ZookeeperRegistryFactory,不过这个ZookeeperRegistryFactory集成自org.apache.dubbo.registry.support.AbstractRegistryFactory
registryFactory.getRegistry(registryUrl)其实是先到了:org.apache.dubbo.registry.support.AbstractRegistryFactory#getRegistry(org.apache.dubbo.common.URL)
在这里插入图片描述
这个方法会在Lock里面获取一个注册中心Registry,如果没有就创建一个createRegistry(url)在这里插入图片描述
org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#ZookeeperRegistry
在这里插入图片描述
先从super(url)一步一步跟上去会看到这个代码
在这里插入图片描述
这里会生成一个.cache的文件在用户home目录下,然后在下面loadProperties()把这些文件中的内容加载到properties里面
然后回到org.apache.dubbo.registry.support.FailbackRegistry#FailbackRegistry在这里插入图片描述
这里检测注册中心并重新连接如果失败了就重新连接
然后再回到:org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#ZookeeperRegistry
在这里插入图片描述
这里开始zookeeper连接了,这个zookeeperTransporter还是一个SPI获取的代理类:ZookeeperTransporter$Adaptive,然后就到了org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperTransporter#connect在这里插入图片描述
再到org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter#createZookeeperClient
在这里插入图片描述
继续跟进到org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient#CuratorZookeeperClient
在这里插入图片描述
这里可以看到使用的是CuratorFrameworkFactory,老版本使用的ZkClient,其实都是连接zk,不了解的可以网上了解下zk的连接ZkClientCuratorFrameworkFactory

//创建CuratorFramework 客户端实例,
//.connectString是集群服务器地址
//.retryPolicy(new RetryNTimes(1, 1000)) 回调策略是RetryNTimes
//.connectionTimeoutMs(timeout) 连接超时时间
//.sessionTimeoutMs  会话超时时间
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
                    .connectString(url.getBackupAddress())
                    .retryPolicy(new RetryNTimes(1, 1000))
                    .connectionTimeoutMs(timeout)
                    .sessionTimeoutMs(sessionExpireMs);
//....省略
//添加连接状态的监听
client.getConnectionStateListenable().addListener(new CuratorConnectionStateListener(url));
//开始连接
client.start();

在添加的状态监听里面org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.CuratorConnectionStateListener#stateChanged
在这里插入图片描述
有对于连接状态的断开重连等恢复连接的操作
最后回到:org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperTransporter#connect
把创建的zk连接保存到Map中,然后创建连接基本就完成了

二. zk节点注册

回到org.apache.dubbo.registry.integration.RegistryProtocol#export
在这里插入图片描述
zk连接成功后,进入org.apache.dubbo.registry.integration.RegistryProtocol#register,最终会调用到:org.apache.dubbo.registry.support.FailbackRegistry#register
在这里插入图片描述
可以看到里面有个doRegister(url);这一步就是向zk发送注册请求
然后继续跟进到了org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#doRegister
在这里插入图片描述
再继续跟进到:org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient#create(java.lang.String, boolean)
注意上面zkClient.create的最后一个参数是在传入的的时候是true
在这里插入图片描述
在这个方法里面,path的值是表示zk中要创建的节点,比如:

dubbo/com.alibaba.dubbo.demo.DemoService/providers/dubbo%3A%2F%2F192.168.100.52%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D2416%26side%3Dprovider%26timestamp%3D1474276306353

当这两个入参进入org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient#create(java.lang.String, boolean)方法时,他会被/分割成下面这样的,然后根据path.lastIndexOf('/')的值是不是再次进入方法,两个入参会不一样,这里有点类似递归,最终结果如下

  • dubbo ➡️ createPersistent(path)创建持久化节点
  • dubbo/com.alibaba.dubbo.demo.DemoService➡️ createPersistent(path)创建持久化节点
  • dubbo/com.alibaba.dubbo.demo.DemoService/providers ➡️createPersistent(path)创建持久化节点
  • dubbo/com.alibaba.dubbo.demo.DemoService/providers/dubbo%3A%2F%2F192.168.100.52%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.0.0%26generic%3Dfalse%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26loadbalance%3Droundrobin%26methods%3DsayHello%26owner%3Dwilliam%26pid%3D2416%26side%3Dprovider%26timestamp%3D1474276306353 ➡️createEphemeral(path)创建临时节点,当接口下线之后这个临时节点也就没了

也就是说总共创建了4个节点,3个持久化的,1个临时的,依次属于层级关系,并不是单独的
实际的创建方法如下
在这里插入图片描述
实际调用的是:org.apache.curator.framework.CuratorFramework#create,和上面连接zk一样使用的CuratorFramework
这里补一下zk的持久化节点和临时节点的概念:

  • 持久节点:该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作来主动删除这个节点
  • 临时节点:临时节点的生命周期和客户端会话绑定在一起,客户端会话失效,则这个节点就会被自动清除

三. 订阅zookeeper

看完zk的节点创建
回到:org.apache.dubbo.registry.integration.RegistryProtocol#export
在这里插入图片描述
进入registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener)走到了:org.apache.dubbo.registry.support.FailbackRegistry#subscribe
在这里插入图片描述
进入:doSubscribe(url, listener); 走到了:org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe
在这里插入图片描述
在这个方法里:zkClient.create(path, false);其中path是:/dubbo/com.alibaba.dubbo.demo.DemoService/configurators,和上面创建节点一样的逻辑,拿着这个path和false做入参,创建相应的持久化节点。
然后继续下一步:zkClient.addChildListener(path, zkListener),对节点进行监听:org.apache.dubbo.remoting.zookeeper.support.AbstractZookeeperClient#addChildListener
在这里插入图片描述
这里会创建一个监听,用于处理收到订阅消息后的逻辑处理:org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient#createTargetChildListener继续跟进到:org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.CuratorWatcherImpl#CuratorWatcherImpl(org.apache.curator.framework.CuratorFramework, org.apache.dubbo.remoting.zookeeper.ChildListener, java.lang.String)
这个构造了一个监听的对象和方法:org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.CuratorWatcherImpl#childEvent
在这里插入图片描述
创建的这个监听对于不同的变化做出不同的处理。然后创建好监听处理逻辑后,
监听的实际调用开始是在:org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient#addTargetChildListener在这里插入图片描述
这个方法里面的client就是CuratorFramework,和连接、创建节点一样的
到这里zk的订阅就完成了
所以zk的订阅总结步骤就是

  1. 创建持久化节点
  2. 创建监听收到订阅消息的处理逻辑
  3. 启动监听

在订阅处理完成后还有一步:org.apache.dubbo.registry.support.FailbackRegistry#notify
在这里插入图片描述
跟进代码:
org.apache.dubbo.registry.support.FailbackRegistry#notify➡️ org.apache.dubbo.registry.support.FailbackRegistry#doNotify➡️ org.apache.dubbo.registry.support.AbstractRegistry#notify(org.apache.dubbo.common.URL, org.apache.dubbo.registry.NotifyListener, java.util.List<org.apache.dubbo.common.URL>)
在这里插入图片描述
最终到了:org.apache.dubbo.registry.support.AbstractRegistry#saveProperties
在这里插入图片描述
把服务端的注册url信息保存到一个用户目录/.dubbo/dubbo-registry-xxxx.cache文件中。这里保存到文件的原因上面注释也写了,是为了在异常情况下拿到要订阅的url。
然后订阅完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值