这是小卷对分布式系统架构学习的第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

下面简述服务注册的过程:

  1. 服务提供者启动时,会将其服务名称,ip地址注册到注册中心;
  2. 服务消费者在第一次调用服务时,会通过注册中心找到相应的服务的IP地址列表,并缓存到本地。当消费者调用服务时,不再请求注册中心,而是直接通过负载均衡算法从IP列表中取一个服务提供者的服务器调用服务;
  3. 当服务提供者的某台服务器宕机或下线时,相应的ip会从服务提供者IP列表中移除。同时,注册中心会将新的服务IP地址列表发送给消费者机器,缓存在消费者本机;
  4. 当某个服务的所有服务器都下线了,那么这个服务也就下线了;
  5. 同样,当服务提供者的某台服务器上线时,注册中心会将新的服务IP地址列表发送给服务消费者机器,缓存在消费者本机;
  6. 服务提供方可以根据服务消费者的数量来作为服务下线的依据

客户端代码示例

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为例的更多相关文章

  1. Dubbo原理解析-注册中心之Zookeeper协议注册中心

    下面我们来看下开源dubbo推荐的业界成熟的zookeeper做为注册中心, zookeeper是hadoop的一个子项目是分布式系统的可靠协调者,他提供了配置维护,名字服务,分布式同步等服务.对于z ...

  2. 服务注册中心之ZooKeeper系列(二) 实现一个简单微服务之间调用的例子

    上一篇文章简单介绍了ZooKeeper,讲了分布式中,每个微服务都会部署到多台服务器上,那服务之间的调用是怎么样的呢?如图: 1.集群A中的服务调用者如何发现集群B中的服务提供者呢? 2.集群A中的服 ...

  3. 服务注册中心之ZooKeeper系列(一)

    一.服务注册中心介绍 分布式服务框架部署在多台不同的机器上.例如服务A是订单相关的处理服务,服务B是订单的客户的相关信息服务.此时有个需求需要在服务A中获取订单客户的信息.如下图: 此时就面临以下几个 ...

  4. Dubbo多注册中心和Zookeeper服务的迁移

    一.Dubbo多注册中心 1. 应用场景 例如阿里有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心. consumer.xml <?xm ...

  5. Spring Cloud注册中心之Zookeeper

    zookeeper可以作为分布式服务的注册中心 在服务端安装zookeeper 参考:https://www.cnblogs.com/conly/p/12267506.html 创建spring bo ...

  6. 服务注册中心之ZooKeeper系列(三) 实现分布式锁

    通过ZooKeeper的有序节点.节点路径不回重复.还有节点删除会触发Wathcer事件的这些特性,我们可以实现分布式锁. 一.思路 zookeeper中创建一个根节点Locks,用于后续各个客户端的 ...

  7. 基于spring-cloud的微服务(1) 服务注册中心eureka

    eureka是Netflix提供的服务注册中心组建,springcloud将其做了封装,作为自己的微服务架构中的一个注册中心组建 下面的例子在IDEA中启动一个eureka的实例,然后提供一个prov ...

  8. 为什么推荐Zookeeper作注册中心

    Zookeeper的数据模型很简单,有一系列被称为ZNode的数据节点组成,与传统的磁盘文件系统不同的是,zk将全量数据存储在内存中,可谓是高性能,而且支持集群,可谓高可用,另外支持事件监听.这些特点 ...

  9. Spring Cloud 系列之 ZooKeeper 注册中心

    什么是注册中心 服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者 url 串.路由信息等.服务注册中心是微服务架构中最基础的设施之一. 注册中心可以说 ...

  10. 学习一下 SpringCloud (二)-- 服务注册中心 Eureka、Zookeeper、Consul、Nacos

    (1) 相关博文地址: 学习一下 SpringCloud (一)-- 从单体架构到微服务架构.代码拆分(maven 聚合): https://www.cnblogs.com/l-y-h/p/14105 ...

随机推荐

  1. 字符串、列表、元组、字典(python)

    文章目录 1.python字符串 1.1 python访问字符串中的值 1.2Python 字符串连接 1.3Python字符串运算符 2.python列表 2.1访问列表中的值 2.2更新列表 2. ...

  2. React 防抖(Debounce)Hook

    防抖动 (debounce)是常见的需求,那么如何搭配 React Hooks 实现防抖动呢,下面演示两种方案. 方案一 副作用防抖 /** * * @param {React.EffectCallb ...

  3. Mellanox hp 544+FLR QSFP 40G 网卡升级固件及性能测试

    烧录命令参考视频: 相关视频: https://www.youtube.com/watch?v=_2-qPV1giEc flint -allow_psid_change -d /dev/mst/mt4 ...

  4. js获取nginx服务器时间

    前端页面js获取nginx服务器时间在实际开发中,我们通常要使用的是服务器端的时间,而不是本机电脑的时间,在js文件中直接通过new Date()获取的时间是本机电脑的系统时间,获取服务器时间的方法如 ...

  5. K均值聚类和代码实现

    K均值聚类是一种无监督学习分类算法. 介绍 对于$n$个$m$维特征的样本,K均值聚类是求解最优化问题: $\displaystyle C^*=\text{arg}\min\limits_{C}\su ...

  6. [python] asyncio库常见问题与实践案例

    本文详细介绍了在使用asyncio库编写异步程序时常见的错误和问题,并进一步通过实践案例进行分析和讨论,以便在项目中更有效地应用asyncio库.有关asyncio库的详细介绍,可参考:Python ...

  7. Mysql分页实现及优化

    通常,我们会采用ORDER BY LIMIT start, offset 的方式来进行分页查询.例如下面这个SQL: SELECT * FROM `t1` WHERE ftype=1 ORDER BY ...

  8. Vue.js 插件

    1.前言 vue的插件其实通过操作Vue这个对象,为其扩展新的功能.例如: // 1. 添加全局方法或 property Vue.myGlobalMethod = function () { // 逻 ...

  9. m4 mac mini本地部署ComfyUI,测试Flux-dev-GGUF的workflow模型10步出图,测试AI绘图性能,基于MPS(fp16),优点是能耗小和静音

    m4 mac mini已经发布了一段时间,针对这个产品,更多的是关于性价比的讨论,如果抛开各种补贴不论,价位上和以前发布的mini其实差别不大,真要论性价比,各种windows系统的mini主机的价格 ...

  10. 重磅推出 Sdcb Chats:一个全新的开源大语言模型前端

    重磅推出 Sdcb Chats:一个全新的开源大语言模型前端 在当前大语言模型(LLM)蓬勃发展的时代,各类 LLM 前端层出不穷.那么,为什么我们还需要另一个 LLM 前端呢? 最初的原因在于质感的 ...