本文介绍基于ZooKeeper的Dubbo服务注册中心的原理。node
1.ZooKeeper中的节点算法
ZooKeeper是一个树形结构的目录服务,支持变动推送,所以很是适合做为Dubbo服务的注册中心。数据结构
注:在ZooKeeper中,节点分为两类,第一类是指构成集群的机器,咱们称之为机器节点;第二类是指数据模型中的数据单元,称之为数据节点ZNode。ZooKeeper将全部数据存储在内存中,数据模型是一棵树(ZNode Tree),由斜杠(/)进行分割的路径,就是一个ZNode,例如/foo/path1。每一个ZNode上都会保存本身的数据内容,同时还会保存一系列属性信息。负载均衡
在ZooKeeper中,Znode可分为持久节点和临时节点两类,所谓持久节点是指一旦这个ZNode被建立了,除非主动进行ZNode的移除操做,不然这个ZNode将一直保存在ZooKeeper上。而临时节点就不同了,它的生命周期和客户端会话绑定,一旦客户端会话失效,那么这个客户端建立的全部临时节点都会被移除。ide
基于ZooKeeper实现的注册中心节点结构示意图:.net
/dubbo:这是dubbo在ZooKeeper上建立的根节点;生命周期
/dubbo/com.foo.BarService:这是服务节点,表明了Dubbo的一个服务;图片
/dubbo/com.foo.BarService/providers:这是服务提供者的根节点,其子节点表明了每个服务真正的提供者;内存
/dubbo/com.foo.BarService/consumers:这是服务消费者的根节点,其子节点表明每个服务真正的消费者;get
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下面新建子节点。一旦服务提供方有变更,zookeeper就会把最新的服务列表推送给消费者。
5)减小服务提供者
全部提供者在ZooKeeper上建立的节点都是临时节点,利用的是临时节点的生命周期和客户端会话相关的特性,所以一旦提供者所在的机器出现故障致使该提供者没法对外提供服务时,该临时节点就会自动从ZooKeeper上删除,一样,zookeeper会把最新的服务列表推送给消费者。
6)ZooKeeper宕机以后
消费者每次调用服务提供方是不通过ZooKeeper的,消费者只是从zookeeper那里获取服务提供方地址列表。因此当zookeeper宕机以后,不会影响消费者调用服务提供者,影响的是zookeeper宕机以后若是提供者有变更,增长或者减小,没法把最新的服务提供者地址列表推送给消费者,因此消费者感知不到。