基于ZooKeeper的服务注册中心

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012006689/article/details/51068812

本文介绍基于ZooKeeper的Dubbo服务注册中心的原理。

1.ZooKeeper中的节点

ZooKeeper是一个树形结构的目录服务,支持变更推送,因此非常适合作为Dubbo服务的注册中心。

注:在ZooKeeper中,节点分为两类,第一类是指构成集群的机器,我们称之为机器节点;第二类是指数据模型中的数据单元,称之为数据节点ZNode。ZooKeeper将所有数据存储在内存中,数据模型是一棵树(ZNode Tree),由斜杠(/)进行分割的路径,就是一个ZNode,例如/foo/path1。每个ZNode上都会保存自己的数据内容,同时还会保存一系列属性信息。

在ZooKeeper中,Znode可分为持久节点和临时节点两类,所谓持久节点是指一旦这个ZNode被创建了,除非主动进行ZNode的移除操作,否则这个ZNode将一直保存在ZooKeeper上。而临时节点就不一样了,它的生命周期和客户端会话绑定,一旦客户端会话失效,那么这个客户端创建的所有临时节点都会被移除。

基于ZooKeeper实现的注册中心节点结构示意图:

这里写图片描述

/dubbo:这是dubbo在ZooKeeper上创建的根节点;

/dubbo/com.foo.BarService:这是服务节点,代表了Dubbo的一个服务;

/dubbo/com.foo.BarService/providers:这是服务提供者的根节点,其子节点代表了每一个服务真正的提供者;

/dubbo/com.foo.BarService/consumers:这是服务消费者的根节点,其子节点代表每一个服务真正的消费者;

2.注册中心的工作流程

接下来以上述的BarService为例,说明注册中心的工作流程。

1)服务提供方启动

服务提供者在启动的时候,会在ZooKeeper上注册服务。所谓注册服务,其实就是在ZooKeeper的/dubbo/com.foo.BarService/providers节点下创建一个子节点,并写入自己的URL地址,这就代表了com.foo.BarService这个服务的一个提供者。

2)服务消费者启动

服务消费者在启动的时候,会向ZooKeeper注册中心订阅自己的服务。其实,就是读取并订阅ZooKeeper上/dubbo/com.foo.BarService/providers节点下的所有子节点,并解析出所有提供者的URL地址来作为该服务地址列表。

同时,服务消费者还会在ZooKeeper的/dubbo/com.foo.BarService/consumers节点下创建一个临时节点,并写入自己的URL地址,这就代表了com.foo.BarService这个服务的一个消费者。

3)消费者远程调用提供者

服务消费者,从提供者地址列表中,基于软负载均衡算法,选一个提供者进行调用,如果调用失败,再选另一个提供者调用。

4)增加服务提供者

增加提供者,也就是在providers下面新建子节点。服务消费方监听provider节点,一旦该节点的内容有变动,provider就会将一个变更通知推送给所有客户端,客户端收到通知后就会主动去provider那拉取最新的服务地址列表。

这里有必要介绍ZK的数据发布与订阅。发布订阅一般有两种设计模式:推和拉。在推模式中,服务器端主动将数据更新发送给所有订阅的客户端;拉模式则是由客户端主动发起请求来获取最新数据,通常客户端都采用定时进行轮询拉取的方式。ZK采用推拉相结合的模式:客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送watcher事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据。

5)减少服务提供者

所有提供者在ZooKeeper上创建的节点都是临时节点,利用的是临时节点的生命周期和客户端会话相关的特性,因此一旦提供者所在的机器出现故障导致该提供者无法对外提供服务时,该临时节点就会自动从ZooKeeper上删除,同样,zookeeper会把provider节点数据变更通知推送给consumer,consumer就会前来拉取最新的服务地址。

6)ZooKeeper宕机之后,consumer和provider还能否通信?

可以。消费者从ZK获取provider地址列表后,会在本地缓存一份。当ZK注册中心所有节点全部宕掉之后,消费者可以使用本地缓存的服务列表和provider进行通信。
ZK的意义在于为consumer和provider提供服务地址的发布/订阅服务,让消费者及时感知最新的服务列表,consumer真正调用provider是通过某种通信协议直接调用,并不依赖ZK。
所以当zookeeper宕机之后,不会影响消费者调用服务提供者,影响的是zookeeper宕机之后如果提供者有变动,增加或者减少,zk无法把变更通知推送给consumer,consumer会因为感知不到变更时间,不去拉取最新的服务列表,导致本地缓存的服务列表有可能过时的。

猜你喜欢

转载自blog.csdn.net/u012006689/article/details/51068812