如何设计一个注册中心?以Zookeeper为例
这是小卷对分布式系统架构学习的第8篇文章,在写第2篇文章已经讲过服务发现了,现在就从组件工作原理入手,讲讲注册中心
以下是面试题:
某团面试官:你来说说怎么设计一个注册中心?
我:注册中心嘛,就要有服务发现的功能,服务启动后把自己的信息注册上去,然后消费端可以拉取生产者的信息嘛,然后就能调用了
某团面试官:那你说说分布式系统中注册中心怎么选型呢?Eureka、Zookpeer、Nacos、Etcd这些中间件,你实际用的时候怎么考虑的?
我:就用Nacos啊,公司里大家都用这个
面试官:......
面试官:我知道了,今天的面试就到这吧......
1.注册中心的功能
设计注册中心时,先来思考下面几个问题:
- 服务如何注册
- consumer如何知道provider
- 注册中心怎么做到高可用,服务发现怎么做的

要想实现一个服务注册中心,必须具备以下功能:
- 服务注册:provider在注册中心完成注册
- 服务注销:服务提供者需在注册中心完成服务下线
- 心跳检测:检查服务提供者的健康状态
- 服务查询:消费者获取服务列表消息
- 服务变更查询:服务发生变更时,消费者通过查询变更获取最新服务列表
- 服务高可用
2.Zookeeper工作原理
我们还是选择一个比较活跃的中间件来展开学习注册中心的工作原理。
Zookeeper的文档官网:Apache ZooKeeper
官网解释Zookeeper名字的由来是因为分布式系统就像个动物园(Zoo),目前国内Dubbo场景下大多选用Zookeeper作为注册中心。官方解释它使用一个具有层次结构的命名空间(类似文件系统),用斜杠(“/”)分隔路径元素,根节点是(“/”)表示,无父节点。通过znodes(ZooKeeper节点)存储数据,如果znode有子节点,则无法删除该znode。这些数据可以被多个应用程序共享,并提供高可用性和一致性。


2.1简单API
ZooKeeper的一个设计目标是提供一个非常简单的编程接口,这些接口故意设计得十分简单。然而,借此接口,您可以实现更高阶的操作,如同步原语、组成员管理、所有权等。编程接口支持以下操作:
- create:在树中的某个位置创建一个节点。
- delete:删除一个节点。
- exists:测试某个位置是否存在节点。
- get data:读取节点中的数据。
- set data:向节点写入数据。
- get children:获取节点的子节点列表。
- sync:等待数据传播。
2.2 服务注册
客户端注册:当一个服务提供者实例启动时,它会向Zookeeper注册到某一路径上。
服务实例通过创建一个znode(通常是临时节点)来注册自己。这个znode包含服务实例的元数据,注册路径为:{service}/{version}/{ip:port}
示例:将我们的HelloService部署启动后,Zookeeper上会创建一个目录:
- /HelloWorldService/1.0.0/192.168.1.100:8080
下面简述服务注册的过程:
- 服务提供者启动时,会将其服务名称,ip地址注册到注册中心;
- 服务消费者在第一次调用服务时,会通过注册中心找到相应的服务的IP地址列表,并缓存到本地。当消费者调用服务时,不再请求注册中心,而是直接通过负载均衡算法从IP列表中取一个服务提供者的服务器调用服务;
- 当服务提供者的某台服务器宕机或下线时,相应的ip会从服务提供者IP列表中移除。同时,注册中心会将新的服务IP地址列表发送给消费者机器,缓存在消费者本机;
- 当某个服务的所有服务器都下线了,那么这个服务也就下线了;
- 同样,当服务提供者的某台服务器上线时,注册中心会将新的服务IP地址列表发送给服务消费者机器,缓存在消费者本机;
- 服务提供方可以根据服务消费者的数量来作为服务下线的依据
客户端代码示例:
ZooKeeper zk = new ZooKeeper("localhost:2181", 3000, null);
String path = "/services/myService";
zk.create(path, "192.168.1.100:8080".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
2.3 心跳检测机制
服务的某台机器下线时,Zookeeper是如何感知到?
zookeeper提供了“心跳检测”功能,它会定时向各个服务提供者发送一个请求(实际上建立的是一个 socket 长连接),如果长期没有响应,服务中心就认为该服务提供者已经“挂了”,并将其删除。
2.4 服务发现
有关服务发现的概念可以看我之前的文章:分布式系统架构2:服务发现
上面说了有新的服务提供者出现时,注册中心是怎么将这些变化通知给消费者客户端的呢?
有2种方式:
- 主动Pull方式:消费者定期从注册中心拉取最新的服务提供者列表,并更新本地缓存。如Eureka
- 发布-订阅模式:消费者实时监听服务更新状态,采用的是监听器+回调机制。Zookeeper用的是发布-订阅模式,客户端在服务节点设置监视器(Watcher)。当节点发生变化(如服务实例上线或下线)时,Zookeeper会通知所有设置了监视器的客户端
2.5 存在问题
Zookeeper作为注册中心不合适,缺少可用性。
zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。
而作为注册中心,可用性的要求高于一致性!
2.6 Zookeeper总结
- Zookeeper的心跳检测,可以自动探测服务提供者机器的宕机或下线;
- Zookeeper的Watch机制,可以将变更的注册列表推给服务消费者;
- Zookeeper是CP模型,不太适合作为注册中心
如何设计一个注册中心?以Zookeeper为例的更多相关文章
- Dubbo原理解析-注册中心之Zookeeper协议注册中心
下面我们来看下开源dubbo推荐的业界成熟的zookeeper做为注册中心, zookeeper是hadoop的一个子项目是分布式系统的可靠协调者,他提供了配置维护,名字服务,分布式同步等服务.对于z ...
- 服务注册中心之ZooKeeper系列(二) 实现一个简单微服务之间调用的例子
上一篇文章简单介绍了ZooKeeper,讲了分布式中,每个微服务都会部署到多台服务器上,那服务之间的调用是怎么样的呢?如图: 1.集群A中的服务调用者如何发现集群B中的服务提供者呢? 2.集群A中的服 ...
- 服务注册中心之ZooKeeper系列(一)
一.服务注册中心介绍 分布式服务框架部署在多台不同的机器上.例如服务A是订单相关的处理服务,服务B是订单的客户的相关信息服务.此时有个需求需要在服务A中获取订单客户的信息.如下图: 此时就面临以下几个 ...
- Dubbo多注册中心和Zookeeper服务的迁移
一.Dubbo多注册中心 1. 应用场景 例如阿里有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心. consumer.xml <?xm ...
- Spring Cloud注册中心之Zookeeper
zookeeper可以作为分布式服务的注册中心 在服务端安装zookeeper 参考:https://www.cnblogs.com/conly/p/12267506.html 创建spring bo ...
- 服务注册中心之ZooKeeper系列(三) 实现分布式锁
通过ZooKeeper的有序节点.节点路径不回重复.还有节点删除会触发Wathcer事件的这些特性,我们可以实现分布式锁. 一.思路 zookeeper中创建一个根节点Locks,用于后续各个客户端的 ...
- 基于spring-cloud的微服务(1) 服务注册中心eureka
eureka是Netflix提供的服务注册中心组建,springcloud将其做了封装,作为自己的微服务架构中的一个注册中心组建 下面的例子在IDEA中启动一个eureka的实例,然后提供一个prov ...
- 为什么推荐Zookeeper作注册中心
Zookeeper的数据模型很简单,有一系列被称为ZNode的数据节点组成,与传统的磁盘文件系统不同的是,zk将全量数据存储在内存中,可谓是高性能,而且支持集群,可谓高可用,另外支持事件监听.这些特点 ...
- Spring Cloud 系列之 ZooKeeper 注册中心
什么是注册中心 服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者 url 串.路由信息等.服务注册中心是微服务架构中最基础的设施之一. 注册中心可以说 ...
- 学习一下 SpringCloud (二)-- 服务注册中心 Eureka、Zookeeper、Consul、Nacos
(1) 相关博文地址: 学习一下 SpringCloud (一)-- 从单体架构到微服务架构.代码拆分(maven 聚合): https://www.cnblogs.com/l-y-h/p/14105 ...
随机推荐
- VScode如何设置浅色侧栏
原文地址:https://blog.csdn.net/KaiSarH/article/details/113241334 vscode主题设置成了浅色,但是侧边栏仍然是灰色,非常讨厌. 在设置中对&q ...
- 二叉树遍历Java版(前中后序的递归,迭代,Morris以及两种特殊的先序遍历)
二叉树的遍历 先序 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode l ...
- vscode+码云(gitee),用git进行源代码管理
使用原因 对于我们经常换电脑来工作的人群,在公司工作完,回家里再用U盘或网盘复制/下载我们的代码,简直是一种折磨,一个项目中断后,时间久了再去想继续的时候,你会发现:到底哪个是最新版的?!U盘满了,这 ...
- JavaScript初始化对象数组
一.{} 我们都知道JavaScript的数据结构是松散的,比如说你定义一个变量 var temp; 那么你可以随手这样定义temp.attr1 = "参数1",因为对于Java ...
- mosquitto(MQTT)服务器搭建和基本使用
一.安装 搭建一个mqtt服务器,这里我们采用mosquitto 1. 下载地址:https://mosquitto.org/download/ 2. 选择windows:https://mosqui ...
- RT-Thread Studio刚新建工程后直接打开main.c编译就board.c里产生报错,解决办法
如题,RT-Thread Studio刚新建工程后直接打开main.c编译就产生报错. 具体为:刚新建了一个stm32F407ZGT6和一个STM32F103RCT6的工程,之后啥代码也没有改,直接打 ...
- K8s之运行时containerd安装和使用
一.containerd 1. 前生今世 很久以前,Docker 强势崛起,以"镜像"这个大招席卷全球,对其他容器技术进行致命的降维打击,使其毫无招架之力,就连 Google 也不 ...
- orange pi 香橙派 zero 刷openwrt当作有wifi的小路由器用
前面写过我用香橙派zero来测量温度 https://www.cnblogs.com/jar/p/15848178.html 最近准备把他改造成路由器 https://www.right.com.cn ...
- Solr的学习使用之(七)Solr高级查询facet、facet.pivot简介 - OnTheRoad_Lee
http://martin3000.iteye.com/blog/1330106 1 .什么是Faceted Search Facet['fæsɪt]很难翻译,只能靠例子来理解了.Solr作者Yoni ...
- Python打包工具之pyinstaller
前言: 近期使用PySimpleGUI开发了一款开发者工具X-助手工具,意打造成平常开发助手,无论是图片还是网址的处理等等都需要这一个工具即可,无需在网上找各个网站去找解决方案, 对于GUI的打包工具 ...