面试:如何设计一个注册中心?

大家好,我是田哥

上周,一位群里的朋友反馈面试情况:

bcc61b8899b69e4b48660916b06ff321.png

今天,给大家分享如何设计一个注册中心。其实这个问题,我之前在知识星球里分享过,可能是因为时间比较久了,加上这位朋友加入不久,还没看到那里。

d56e75c37f1c79fadadab0ebca55ea90.png

不管是出于面试,还是深入学习注册中心,关于如何设计一个注册中心都是一个很好的话题。

假设现在我们系统有两个小系统(这里只是个假设,可能很多人并没有做过类似的业务,注意只是一个业务场景而已):

  • 订单系统

  • 商品系统

单个系统分别部署在不同服务器上,如果我们订单系统需要调用商品系统的某个服务(聊简单点,别扯什么缓存之类的):

fd4a7b0337cdfca65f0fa2db2ca3bf4f.png


怎么调用?

方法1:商品系统开发的朋友告诉你对应的地址。

852a966c4e56f1ab7c0ef1bd01be8569.png


方法2:商品系统开发的朋友把对应API地址存放到某个地方。

7fed865123a8d6db512da1e89e03a830.png


方法3:直接通过Nginx,使用域名进行转发到某个实例上。

cd54ea2c14df2e01b80abf473e2955f3.png


这时候,订单系统就可以通过上述方法调用商品系统的API了。

问题来了

实际线上环境中,很少是单体机构的,很多都是做了集群的,也就是说每个服务会有N个实例,少则几个几十个,多则几百上千上万。如果此时我们还用上面三种方法,当我们的商品系统某个服务下线(宕机了),或者新增实例,此时是非常的头疼。

所以,注册中心就来了。

注册中心来了

我们能不能搞一个第三方的节点,这个节点就用来存放我们商品系统的服务信息,这样一来,其他系统需要服务信息,直接去第三方节点上去获取即可。此时,其他系统只要知道这个第三方的节点地址就可以了。这个第三方的节点,我们也称之为注册中心

下面我们用服务提供方(商品系统)称之为provider,服务调用方(订单系统)我们称之为consumer。

如何设计一个注册中心

我们需要解决如下几个问题:

  • 服务如何注册

  • consumer如何知道provider

  • 服务注册中心如何高可用

  • 服务上下线,消费端如何动态感知

服务注册

733f2a08ee600cd840c470768b6ddc64.png


当我们把服务信息注册上去后,就应该是:

ac85a70b5fd85fdc07d8744835e0ff43.png


服务列表保存通常有三种方式:本地内存、数据库、第三方缓存系统

注册上去后,consumer需要服务地址的时候,就可以用相应key去注册中心获取对应的服务列表。

c791bc85317bf2a959e794912ed99703.png


同一个服务注册中心,我们可以注册多个服务,比如用户服务、商品服务、订单服务...

服务消费

cfd44e17f8c2e6026906eba9d0c6e8e6.png


consumer端通过key获取指定的服务地址列表。

以上的还是蛮简单的吧,简单来说,我们就是引用了一个第三方的服务来存放我们的服务提供者列表。并且以key-value的形式存储,key我们可以理解为服务名称,value就是服务实例列表。

d159b4446a6acbf108de933b73ad1cda.png


注册中心高可用

高可用无非就是做集群,我们可以对注册中心部署多个节点。在消费端consumer只需要知道一个服务注册中心集群地址cluster-url即可。

31cd7f01a3a6a7015f2033cb107dcbe2.png


动态感知服务上下线

consumer拿到服务列表后,会把服务列表保存起来,保存到本地缓存里。

0369742ce3d5cf0d1bc9cd2f66c91975.png


consumer通过一定的负载均衡算法,选择出一个地址,最后发起远程的调用。

b7986fa82b988ca539d89400f54fd263.png


如果我们的服务节点挂掉一个了,怎么办?

2f468ec01237c6cb527458baf5d4e386.png


此时,服务注册中心的服务列表还是之前的列表,如果consumer调用到过掉的节点上,那岂不是会出问题呀。

所以,我们的服务注册中心需要知道哪个服务节点挂了,然后从对应服务列表里删除。

有种办法叫做心跳检测heartBeat,即就是服务注册中心,每隔一定时间去监测一下provider,如果监测到某个服务挂了,那就把对应服务地址从服务列表中删除。

根据心跳检测,来提出无效服务。

4f2ac0864fbd19355eac6333818b9721.png


可是不对呀,此时consumer端本地列表里还有过掉的服务地址,怎么办呢?

或者是,在增加一个新的服务节点

8fc7b910ca9ceda199ad08d564677e71.png


对于服务注册中心来说,就是服务列表里增加一个服务地址。

但是在消费端存在同样的问题,就是服务注册中心的服务列表和consumer端的服务列表不一样了。

如何让consumer端也动态感知呢?

其实很简单,此时,我们得思维换一下,因为consumer的服务列表是来自于服务注册中心,我们就可以把consumer理解为消费端,服务注册中心理解为服务端。此时,consumer端就可以去服务端(服务注册中心)拉取provider服务列表。

通常有两种方案:push和pull

  • push:服务注册中心主动推送服务列表给consumer。

  • pull:consumer主动从注册中心拉取服务列表。

90ebdca5a7cb2bb39b469f261e66a973.png


不管是push还是pull,都会存在consumer和服务注册中心的通信管道。如果他们之间断开了,那就无法获取服务列表了。

还有就是服务注册中心知道consumer的地址,比如

我得知道你的微信好友,不然我怎么把我手里的资源发给你

我们的网络通信,必然会存在监听的动作。

如果服务注册中心要push到consumer,此时他们之间需要建立一个会话,所以,在服务注册中心会维护一个会话管理的模块。还有一种方式就是consumer提供一个API,这个API给服务注册中心进行回调。

本质是我们是使用HTTP协议还是使用Socket监听

push有个不好点,那就是服务注册中心需要维护大量的会话,而且还需要对每个会话维持一个心跳,一遍知晓这些会话状态,得确保这些consumer能收到数据,

另外就是pull,pull其实就相对push就简单多了。pull和我们前面说的心跳机制是类似的,consumer端启动定时任务,每个多久拉取服务注册中心的服务列表。pull也不需要去维护大量的会话,我只需要每隔多久调用接口拉取服务列表即可。但是这里还是会存在一个问题,因为是定时去拉取,所以会存在一定的数据延迟,比如consumer刚刚拉取服务列表,但就在拉取结束的后,某个服务provider挂了,consumer就要等下次拉取才知道对应服务provider挂了。

如果定时任务是每隔30秒拉去一次,那就是说,延迟最长时间是30秒。

还有一种方式long-pull,也叫长轮询,是上面两种方案的优化方案,consumer发起拉取请求时,先把这个请求hold住,当服务注册中心有发生变化后,consumer端能立马感知。

关于长轮询:

与简单轮询相似,只是在服务端在没有新的返回数据情况下不会立即响应,而会挂起,直到有数据或即将超时

优点:实现也不复杂,同时相对轮询,节约带宽

缺点:还是存在占用服务端资源的问题,虽然及时性比轮询要高,但是会在没有数据的时候在服务端挂起,所以会一直占用服务端资源,处理能力变少

应用:一些早期的对及时性有一些要求的应用:web IM 聊天

这样,我们就搞定了所谓的服务上下线动态感知。

通过上面的服务注册、服务消费、注册中心高可用以及动态感知服务的上下线,这就是我们去实现一个服务注册中心的通用模型。

总结

关于如何设计一个注册中心,无非重点关以下几点:

  • 服务是如何注册

  • 消费端如何获取服务

  • 如何保证注册中心的高可用

  • 动态感知服务的上下线

好了,今天就跟大家分享这么多,希望能给你带来点点帮助。

如果有点点帮助,那就顺手来个三连呗:点赞、转发、再看,谢谢啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/537544.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

五步搭建:用HelpLook零代码创建企业专属知识库

随着企业的不断发展,拥有一个强大的企业知识库不仅能促进内部沟通,还能展示企业专业形象。HelpLook作为一款简单好用AI知识库搭建系统,只需5步,即可能够零代码帮助企业建立专属知识库。 一、如何从0到1搭建企业知识库?…

ARL资产侦察灯塔系统

1、资产侦察灯塔系统搭建 1.1、系统要求 目前暂不支持 Windows,Linux 和 MAC 建议采用 Docker 运行,系统配置最低 2 核 4G。 由于自动资产发现过程中会有大量的的发包,建议采用云服务器可以带来更好的体验 实验环境: 系统&…

数据结构复习指导之顺序表上基本操作的实现(插入、删除、查找)

文章目录 顺序表基本操作实现 知识总览 1.顺序表的初始化 1.1静态分配顺序表的初始化 1.2动态分配顺序表的初始化 2.插入操作 2.1插入操作流程 2.2插入操作时间复杂度 3.删除操作 3.1删除操作流程 3.2删除操作时间复杂度 4.查找操作 4.1按位查找 4.2按位查找时间…

NetBox4 安装指南-为网络工程师打造的基础设施管理(全面汉化)

介绍 NetBox 是用于建模和记录现代网络的领先解决方案。由 结合 IP 地址管理 (IPAM) 的传统应用和 具有强大 API 和扩展的数据中心基础架构管理 (DCIM), NetBox 为推动网络自动化提供了理想的“事实来源”。 NetBox 在…

弹性云服务器性能对比(内附测试数据),快快网络服务器崭露头角

随着计算技术的不断革新,云服务器已成为企业和个人部署应用与服务的首选。尤其线上业务日益盛行的今天,云服务商的实力更是备受瞩目。对于企业而言,高稳定,存储速度都是不可或缺的基本要求,这些都对公有云的云端编解码…

阿里云服务器部署网站(图文详解)

一,准备工作 1.1,点击:注册阿里云账号 输入:账户名,登录密码,手机号。 1.2,域名注册和备案 详细请参考:阿里云域名购买流程和备案流程 1.3,准备服务器 详细请参考&a…

【QT入门】 Qt自定义控件与样式设计之QPushButton实现鼠标悬浮按钮弹出对话框

往期回顾: 【QT入门】 Qt自定义控件与样式设计之qss选择器-CSDN博客 【QT入门】 Qt自定义控件与样式设计之QLineEdit的qss使用-CSDN博客 【QT入门】Qt自定义控件与样式设计之QPushButton常用qss-CSDN博客 【QT入门】 Qt自定义控件与样式设计之QPushButton实现鼠标悬…

观察者模式:实现高效事件驱动编程的策略

在软件开发中,观察者模式是一种关键的行为型设计模式,用于建立对象间的一种依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都会得到通知并被自动更新。这种模式是事件监听和响应编程的基石。本文将详细介绍观察者模式的定…

【JAVA基础篇教学】第十篇:Java中Map详解说明

博主打算从0-1讲解下java基础教学,今天教学第十篇:Java中Map详解说明。 在 Java 编程中,Map 接口代表了一种键值对的集合,每个键对应一个值。Map 接口提供了一系列操作方法,可以方便地对键值对进行增删改查等操作。本…

【汇编】_Visual Studio2019写32位汇编

目录 第一步:创建新项目 1. 空项目—下一步 2. 选择位置—填写项目名—创建 第二步:项目生成依赖项 1. 右击项目名—生成依赖项—生成自定义 2. 选中masm—确定 第三步:创建源文件 1. 源文件—添加—新建项 2. 选择C文件—创建新文件…

数据库被rmallox勒索病毒加密,如何还原?

近年来,网络安全问题日益严峻,勒索病毒作为其中的一种恶意软件,已成为网络安全领域的一大难题。其中,rmallox勒索病毒以其高度的隐蔽性和破坏性,给不少企业和个人带来了严重损失。本文将从rmallox勒索病毒的特点、传播…

Unity-超级方便的Excel 读写插件

超级无敌棒棒糖🖌 🌭功能介绍🍕 Demo🌳准备一个数据类🌳准备一个Excel🌳导入Excel🌳行数据自动转换🌳导出到Excel 🍱新增映射字段类型 🌭功能介绍 &#x1f…

监控系统泛滥:CTO 面临的隐形成本危机

在信息技术飞速发展的今天,构建和维护现代化的数字系统变得日益复杂和关键;在这样的背景下,监控系统的作用变得尤为突出。正如业界广泛流传的一句经验之谈“无监控,不运维”所揭示的道理一样,对于任何具有一定复杂性的…

进程程序替换

文章目录 程序替换原理替换函数函数解释调用举例 程序替换原理 用新进程的代码和数据覆盖旧进程的代码和数据,没有创建新进程,用旧进程的壳执行了新进程。 站在被替换进程的角度:本质就是程序从磁盘加载到了内存。 怎么加载呢?…

【电控笔记6】电流回路+延迟效应

问题提出 数字控制系统的delay: 5.4节有介绍T0=0.5TS 低通滤波器的时间常数? 可用示例程序 m2 2 1b 如下图画出开环系统的伯德图进行比较,如图 2-2-4 所示,由于延迟组件会侵蚀系统的相位,因此从图可以看出,加入延迟效应后,q轴电流回路的相位裕度(Phase Margin) 从…

【数据结构】单链表(二)

目录 1.查找数据 2.指定位置插入和删除节点 2.1 指定位置之前插入节点 2.2 指定位置之后插入节点 2.3 删除指定位置节点 2.4 删除指定位置之后的节点 3.销毁链表 我们接着上一篇【数据结构】单链表(一)-CSDN博客 来继续实现单链表 1.查找数据 在…

c# wpf datagrid 简单试验

1.概要 datagrid 一个列表类的控件 2.代码 <Window x:Class"WpfApp2.Window3"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.mic…

关于 STM32WL LSE 添加反馈电阻后无法起振问题

1. 问题描述 客户调试 STM32WLE5JB 样机的时候遇到这样一个问题&#xff1a;在调试 LPUART&#xff0c;不打开外部时钟的时候&#xff0c;能够正常打印&#xff0c;若开启外部的 HSE 和 LSE 后就没有打印。 2. 问题确认 发现上述问题时&#xff0c;客户使用 STM32CubeMX 生成…

数字图像处理项目——模糊图像边缘检测算法设计及实现(论文/代码)

完整的论文代码见文章末尾 以下为部分内容 摘要 本研究旨在针对大脑核磁图像中的黑色腔体进行有效分割&#xff0c;以提供可靠的腔体定位和分析。为此&#xff0c;采用了三种常用的图像分割方法&#xff1a;8邻域区域生长法、Canny算子边缘检测和8邻域边界跟踪法。 首先&…

ES13:类的新增特性、最外层的await、at...

1-类的新增特性 类私有属性和方法&#xff1a;# class Person{// 不需要传参、一开始就需要初始化的&#xff0c;就可以在类的最外面直接声明这个成员state{a:1,b:2}constructor(name,age){this.namename;this.ageage;}}在属性和方法前加#表示私有 #obj{} #prest(){}静态成员…