设为首页 加入收藏

TOP

Dubbo 中 Zookeeper 注册中心原理分析(一)
2023-07-25 21:43:48 】 浏览:81
Tags:Dubbo Zookeeper

vivo 互联网服务器团队- Li Wanghong

本文通过分析Dubbo中ZooKeeper注册中心的实现ZooKeeperResitry的继承体系结构,自顶向下分析了AbstractRegistry(提供了服务数据的本地缓存)、FailbackRegistry(服务注册订阅相关的异常重试)、CacheableFailbackRegistry(Dubbo在URL推送模型做的优化)、ZooKeeperRegistry(ZooKeeper注册中心实现原理)的源码,详细介绍了Dubbo中ZooKeeper注册中心的实现原理。

当服务提供者启动时,服务提供者将自己提供的服务信息注册到注册中心,注册中心将这些信息记录下来。服务消费者启动时,向注册中心发起订阅,将自己感兴趣的服务提供者的信息拉取到本地并缓存起来,用于后续远程调用。另外,注册中心能够感知到服务提供者新增或者下线,并更新自己的服务信息,同时通知服务消费者告知服务提供者新增/下线,从而消费者也可以动态感知到服务提供者的变化。

图片

一、ZooKeeper注册中心

ZooKeeper 是 Apache 的顶级项目。ZooKeeper 为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名服务、配置管理和分布式锁等分布式的基础服务。在解决分布式数据一致性方面,ZooKeeper 并没有直接采用 Paxos 算法,而是采用了名为 ZAB 的一致性协议。

1.1 ZooKeeper数据结构

ZooKeeper 的数据模型是一个树形结构的文件系统。Dubbo服务在ZooKeeper中的数据结构(旧版模型,Dubbo2.7版本后路由数据、配置数据不再写到该目录下)如下图所示。

图片

 

ZooKeeper中的节点分为持久节点、持久顺序节点、临时节点、临时顺序节点。Dubbo使用ZooKeeper作为注册中心时,不关心节点的创建顺序,只会创建持久节点和临时节点。

  • 持久节点: 服务注册后保证节点不会丢失,注册中心重启也会存在 。

  • 临时节点: 服务注册后连接丢失或session超时,注册的节点会自动被移除 。

1.2 ZooKeeper的Watcher机制

客户端和服务器维持数据交互通常有两种形式:

  1. 客户端定时向服务器轮询

  2. 服务器主动向客户端推送数据

ZooKeeper采用的是方式2,主动向客户端推送数据。客户端注册监听它关心的节点(注册Watcher监听指定节点),当节点状态发生变化(数据变化、子节点增减变化)时,则相应的Watcher被触发,ZooKeeper 服务会通知客户端,这就是Watcher机制。

Watcher有以下特点:

  1. 主动推送:Watcher被触发时,由ZooKeeper主动将更新推送给客户端,而不需要客户端轮询。

  2. 一次性:在节点上注册Watcher监听后,当节点状态发生变化时该Watcher只会被触发一次,如果客户端想再收到后续发生变化的通知,需要重新再注册一次Watcher。

  3. 可见性:如果一个客户端在读请求中附带 Watcher,Watcher 被触发的同时再次读取数据,客户端在得到 Watcher 消息之前肯定不可能看到更新后的数据。换句话说,更新通知先于更新结果。

  4. 顺序性:如果多个更新触发了多个 Watcher ,那 Watcher 被触发的顺序与更新顺序一致。

1.3 ZooKeeper会话机制

ZooKeeper 客户端通过 TCP 长连接连接到 ZooKeeper 服务集群。会话 (Session) 从第一次连接开始就已经建立,之后通过心跳检测机制来保持有效的会话状态。通过这个连接,客户端可以发送请求并接收响应,同时也可以接收到 Watch 事件的通知。一旦一台客户端与一台服务器建立连接,这台服务器会为这个客户端创建一个新的会话。

每个会话都会有一个超时时间。若由于服务器压力过大、网络故障等各种原因导致客户端连接断开时,只要在会话超时时间之内能够重新连接上ZooKeeper服务器,那么之前创建的会话仍然有效。若服务器在超时时间内没有收到任何请求,则相应会话被视为过期。一旦会话过期,就无法再重新打开,且任何与该会话相关的临时 节点都会被删除。

通常来说,会话应该长期存在,而这需要由客户端来保证。客户端可以通过心跳方式来保持会话不过期。

1.4 使用ZooKeeper作为注册中心

如下图所示,服务提供者(集成了ZK客户端)在服务启动时,会通过ZK客户端与ZK服务端建立连接,将服务提供者信息(提供者的IP地址、端口、服务接口信息等)注册到ZooKeeper服务端,这时会在ZooKeeper服务端生成一个临时节点来存储这些服务信息,这就是服务提供者的注册操作。

服务消费者(集成了ZK客户端)在服务启动时,会通过ZK客户端与ZK服务端建立连接,拉取自己感兴趣的服务提供者信息并缓存到本地,同时也会对自己感兴趣的节点(比如服务提供节点)注册Watcher监听。后续发起远程调用时,会从本地缓存的服务提供者信息通过负载均衡等策略选择一台服务提供者发起服务调用。

如果服务提供者扩容新增了机器,服务提供者会向ZK发起新的注册操作,在对应的目录下创建临时节点(代表这台新增的服务提供者信息),同时会触发之前服务消费者注册的Watcher监听,ZooKeeper服务端会将变更信息推送到服务消费,服务消费者在接收到变更后会更新自己本地的服务提供者信息,这样就完成了服务的自动扩容。同样的,当某台服务提供者下线,它与ZooKeeper服务端的连接会断掉,因为服务注册时创建的是临时节点,因此当连接断掉后,该临时节点会被删除,同时会触发之前服务消费者注册的Watcher监听,相应的服务消费者会收到通知刷新自己本地的服务提供者信息缓存。

图片

二、源码分析

图片

Node,Dubbo中用Node来表示抽象节点,Dubbo中的核心概念Registry、Invoker等都实现了接口Node。

RegistryService定义了注册服务需要提供的基本能力,即增删改查。Registry接口继承了Node和Registry接口,它表示拥有注册中心能力的节点。其中定义了4个默认方法,其中的reExportRegister和reExportUnRegiser方法都是委托给RegisterService的相应方法。

AbstractRegistry实现了Registry接口中的方法,它在内存中实现了注册数据的读写改动,实现了本地缓存的功能。

FailbackRegistry继承了AbstractRegistry,结合时间轮,提供了失败重试的能力。

CacheableFailbackRegistry针对URL推送模型做了优化,减少了URL的创建。

ZooKeeperRegistry提供了基于ZooKeeper的注册中心实现。

下面重点分析AbstractRegistry、FailbackRegistry、CacheableFailbackRegistry和ZooKeeperRegistry。

2.1 AbstractRegistry

AbstractRegistry实现了Registry接口中的方法,它在内存中实现了注册数据的读写改动,从而可以就降低注册中心的压力。从前文继承体系结构可以看出,Dubbo中的注册中心实

首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇SpringBoot学习笔记 - 构建、简化.. 下一篇easy excel 导入导出

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目