Zookeeper作为服务注册与发现的解决方案,它有如下优点:
1. 它提供的简单API
2. 已有互联网公司(例如:Pinterest,Airbnb)使用它来进行服务注册与发现
3. 支持多语言的客户端
4. 通过Watcher机制实现Push模型,服务注册信息的变更能够及时通知服务消费方
缺点是:
1. 引入新的Zookeeper组件,带来新的复杂性和运维问题
2. 需自己通过它提供的API来实现服务注册与发现逻辑(包含Python与Java版本)
我们对上述几个方案的优缺点权衡之后,决定采用了基于Zookeeper实现自己的服务注册与发现。
基于Zookeeper的服务注册与发现架构
服务提供者
服务提供者作为服务的提供方将自身的服务信息注册到服务注册中心中。服务信息包含:
▪ 隶属于哪个系统
▪ 服务的IP,端口
▪ 服务的请求URL
▪ 服务的权重等等
服务注册中心
服务注册中心主要提供所有服务注册信息的中心存储,同时负责将服务注册信息的更新通知实时的Push给服务消费者(主要是通过Zookeeper的Watcher机制来实现的)。
服务消费者
服务消费者主要职责如下:
1. 服务消费者在启动时从服务注册中心获取需要的服务注册信息
2. 将服务注册信息缓存在本地
3. 监听服务注册信息的变更,如接收到服务注册中心的服务变更通知,则在本地缓存中更新服务的注册信息
4. 根据本地缓存中的服务注册信息构建服务调用请求,并根据负载均衡策略(随机负载均衡,Round-Robin负载均衡等)来转发请求
5. 对服务提供方的存活进行检测,如果出现服务不可用的服务提供方,将从本地缓存中剔除
服务消费者只在自己初始化以及服务变更时会依赖服务注册中心,在此阶段的单点故障通过Zookeeper集群来进行保障。在整个服务调用过程中,服务消费者不依赖于任何第三方服务。
实现机制介绍
Zookeeper数据模型介绍
在整个服务注册与发现的设计中,最重要是如何来存储服务的注册信息。
在设计基于Zookeeper的服务注册结构之前,我们先来看一下Zookeeper的数据模型。Zookeeper的数据模型如下图所示:
Zookeeper数据模型结构与Unix文件系统很类似,是一个树状层次结构。每个节点叫做Znode,节点可以拥有子节点,同时允许将少量数据存储在该节点下。客户端可以通过监听节点的数据变更和子节点变更来实时获取Znode的变更(Wather机制)。