当前位置: 首页 > news >正文

【RocketMQ】NameServer总结

NameServer是一个注册中心,提供服务注册和服务发现的功能。NameServer可以集群部署,集群中每个节点都是对等的关系(没有像ZooKeeper那样在集群中选举出一个Master节点),节点之间互不通信。
服务注册
Broker启动的时候会向所有的NameServer节点进行注册,注意这里是向集群中所有的NameServer节点注册,而不是只向其中的某些节点注册,因为NameServer每个节点都是对等的,所以Broker需要向每一个节点进行注册,这样每一个节点都会有一份Broker的注册信息。

服务发现
Broker向NameServer注册以后,生产者Producer和消费者Consumer就可以从NameServer中获取所有注册的Broker信息,并从中选取Broker进行消息的发送和消费。

以生产者为例,在NameServer集群部署模式下,生产者会从多个NameServer中随机选取一个进行通信,从中拉取所有Broker的注册信息,并将拉取到的信息进行缓存,生产者知道了Broker的信息后,就可以得知Topic的分布情况,然后选取一个消息队列,与其所在的Broker通信进行消息的发送。如果通信的Nameservre宕机,消费者会轮询选择下一个NameServer。

为什么需要NameServer?

在使用RocketMQ的时候,为了提升性能以及应对高并发的情况,一般都会使用多个Broker进行集群部署,假设没有注册中心,对于Broker来说,如果想获取到集群中所有的Broker信息(生产者和消费者需要通过某个Broker获取整个集群的信息,从而得到Topic的分布情况),每个Broker都需要与其他Broker通信来交换信息,以此来得到集群内所有Broker的信息,在Broker数量比较大的情况下,会造成非常大的通信压力。

为什么不使用zookeeper这样的分布式协调组件?
首先zookeeper的实现复杂,引入zookeeper会增加系统的复杂度,并且zookeeper在CAP中选择了CP,也就是一致性和分区容错性,从而牺牲了可用性,为了保持数据的一致性会在一段时间内会不可用。

而NameServer在实现上简单,RocketMQ的设计者也许认为对于一个消息队列的注册中心来说,一致性与可用性相比,可用性更重要一些,至于一致性可以通过其他方式来解决。

假如选择了CP的ZooKeeper,先不考虑其他原因,在ZooKeeper不可用的时候,如果有消费者或生产者刚好需要从NameServer拉取信息,由于服务不可用,导致生产者和消费者无法进行消息的生产和发送,在高并发或者数据量比较大的情况下,大量的消息无法发送/无法消费影响是极大的,而如果选择AP,即便数据暂时处于不一致的状态,在心跳机制的作用下也可以保证数据的最终一致性,所以RocketMQ选择了自己实现注册中心,简单并且轻量

举个例子,假如集群中有三个Broker(分别为 A、B、C),向三台NameServer进行了注册(也分别为A、B、C),消费者从NameServer中获取到了三个Broker的信息,如果此时BrokerA需要停止服务,分别通知三台NameServer需要下线,从NameServer中剔除该Broker的信息,由于网络或者其他原因,NameServer A和B收到了下线的请求,NameServer C并未收到,此时就处于数据不一致的状态,如果某个消费者是与NameServer C进行通信,会认为Broker还处于可用的状态:

对于这种情况,首先NameServer与Broker之间会有一个心跳机制,NameServer定时检测在某个时间范围内是否收到了Broker发送的心跳请求,如果未收到,会认为该Broker不可用,将其剔除(在下面会讲到),所以对于NameServer来说,尽管数据会暂时处于不一致的状态,但是可以保证过一段时间之后恢复数据的一致性,也就是最终一致性。

对于消费者来说,既然可以从NameServer C中获取到Broker A的信息,那么消费者就认为Broker A可用,如果发送的消息所在的消息队列在Broker A中,就会与Broker A通信进行发送,但实际上Broker A实际上是不可用的,消息会发送失败,所以RocketMQ设计了消息重试机制以及故障延迟机制。

Broker注册

Broker启动后会开启定时向NameServer进行注册(发送心跳包)的任务,发送心跳包的时间间隔可以在配置文件中进行设置,但是最长不能超过10s,也就是说Broker最长10秒钟会向Nameserver发送一次心跳包。

NameServer收到Broker的注册请求(心跳包)后,会判断Broker之前是否已经注册过,如果未注册过将其加入到注册的Broker集合brokerAddrTable中,同时也会记录收到注册请求的时间,将其加入到brokerLiveTable中,里面记录了NameServer收到每个Broker发送心跳包的时间,在进行心跳检测的时候根据这个时间戳来判断是否在规定时间内未收到该Broker发送的心跳包。

读写锁
由于NameServer可能同时收到多个Broker的注册以及生产者或者消费者的拉取请求,为了保证数据的一致性(因为有读写请求同时发生或者写与写请求同时发生),在处理相关请求的时候需要加锁,为了提高性能,使用了ReadWriteLock读写锁,处理注册请求时会先添加写锁,处理拉取请求时添加读锁,这样如果某一时刻都是读的请求可以同时进行,互不影响,如果有写请求,其他请求就需要等锁释放才可以进行往下进行。如果不使用读写锁,直接对所有的请求加锁,会影响性能,实际上读与读之间并不需要加锁。

心跳检测

Nameserver在启动的时候会开启一个用于心跳检测的定时任务(每10s执行一次),定时扫描处于不活跃状态的Broker,如果在规定时间内未收到某个Broker的心跳包,会认为此Broker不可用,需要将其进行剔除。

上面说到brokerLiveTable保存了当前NameServer收到的心跳数据,里面记录了每一个Broker最近进行注册/发送心跳的时间戳,所以只需遍历brokerLiveTable,获取每一个Broker最近一次发送心跳的时间进行判断,如果上一次发送心跳的时间 + 过期时间(120s) 小于 当前时间,也就是超过120s没有收到某个Broker的心跳包,则认为此Broker已下线,将Broker移除

Broker下线

正常下线
当Broker下线的时候会向NameServer发起取消注册的请求,NameServer收到请求后会将Broker剔除。

异常下线

如果Broker异常宕机,或者发送给NameServer的取消注册请求由于某些原因并未发送成功,NameServer可能并未感知到Broker的下线,由于心跳机制定时检测的功能,会在一段时间后发现未收到Broker的心跳请求,主动将Broker剔除。

生产者和消费者

生产者和消费者都会定时从NameServer中更新Broker的注册信息,默认是30s进行一次更新:

public class MQClientInstance {private void startScheduledTask() {this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {try {// 更新路由信息 MQClientInstance.this.updateTopicRouteInfoFromNameServer();} catch (Exception e) {log.error("ScheduledTask updateTopicRouteInfoFromNameServer exception", e);}}}, 10, this.clientConfig.getPollNameServerInterval(), TimeUnit.MILLISECONDS);}
}

对应的相关源码可参考:

【RocketMQ】【源码】NameServer的启动
【RocketMQ】【源码】Broker服务注册

相关文章:

【RocketMQ】NameServer总结

NameServer是一个注册中心,提供服务注册和服务发现的功能。NameServer可以集群部署,集群中每个节点都是对等的关系(没有像ZooKeeper那样在集群中选举出一个Master节点),节点之间互不通信。 服务注册 Broker启动的时候会…...

Wordcloud | 风中有朵雨做的‘词云‘哦!~

1写在前面 今天可算把key搞好了,不得不说🏥里手握生杀大权的人,都在自己的能力范围内尽可能的难为你。😂 我等小大夫也是很无奈,毕竟奔波霸、霸波奔是要去抓唐僧的。 🤐 好吧,今天是词云&#x…...

《孤注一掷》现实版:29万打水漂,华为程序员也躲不过的诈骗

明天周五,约吗? 不管怎样,反正播妞已经订好了《孤注一掷》的电影票。不为别的,《孤注一掷》太敢拍了!!! 美女荷官在线发牌,高知程序员在线养“猪”,诈骗头目“虔诚”拜…...

C语言库函数之 qsort 讲解、使用及模拟实现

引入 我们在学习排序的时候&#xff0c;第一个接触到的应该都是冒泡排序&#xff0c;我们先来复习一下冒泡排序的代码&#xff0c;来作为一个铺垫和引入。 代码如下&#xff1a; #include<stdio.h>void bubble_sort(int *arr, int sz) {int i 0;for (i 0; i < sz…...

Maven之mirrorof范围

mirrorOf 是 central 还是 * 的问题 在配置阿里对官方中央仓库的镜像服务器时&#xff0c;我们使用到了 <mirror> 元素。 <mirror><id>aliyunmaven</id><mirrorOf>central</mirrorOf><name>阿里云公共仓库</name><url>…...

游戏中的UI适配

引用参考&#xff1a;感谢GPT UI适配原理以及常用方案 游戏UI适配是确保游戏界面在不同设备上以不同的分辨率、屏幕比例和方向下正常显示的关键任务。下面是一些常见的游戏UI适配方案&#xff1a; 1.分辨率无关像素&#xff08;Resolution-Independent Pixels&#xff09;&a…...

【Linux命令详解 | gzip命令】 gzip命令用于压缩文件,可以显著减小文件大小

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 基本压缩和解压2. 压缩目录3. 查看压缩文件内容4. 测试压缩文件的完整性5. 强制压缩6. 压缩级别7. 与其他命令结合使用8. 压缩多个文件9. 自动删除原文件 总结 简介 在Linux中&#xff0c;gzip命令是一款强大的文…...

IP 协议的相关特性和数据链路层相关知识总结

目录 IP 协议的相关特性 一、IP协议的特性 二、 IP协议数据报格式 三、 IP协议的主要功能 1. 地址管理 动态分配 IP地址 NAT机制 NAT背景下的通信 IPV6 2. 路由控制​​​​​​​ 3.IP报文的分片与重组 数据链路层相关知识 1、以太网协议&#xff08;Ethernet&#xff09; 2.M…...

探索C语言中的常见排序算法

探索C语言中的常见排序算法 排序算法是计算机科学中至关重要的基础知识之一&#xff0c;它们能够帮助我们对数据进行有序排列&#xff0c;从而更高效地进行搜索、插入和删除操作。在本篇博客中&#xff0c;我们将深入探讨C语言中的一些常见排序算法&#xff0c;包括它们的工作…...

【UE】Web Browser内嵌网页在场景中的褪色问题

使用WebBrowser放置在场景中时&#xff0c;网页颜色会出现异常的褪色。 这是因为 Web 浏览器插件以 sRGB 格式输出其颜色数据&#xff0c;而 Widget/3D Widget 需要线性 RGB 格式的数据。 可以通过创建在 3D Widget 中使用的新材质&#xff08;而不是默认的 Widget3DPassthr…...

rust入门系列之Rust介绍及开发环境搭建

Rust教程 Rust基本介绍 网站: https://www.rust-lang.org/ rust是什么 开发rust语言的初衷是&#xff1a; 在软件发展速度跟不上硬件发展速度&#xff0c;无法在语言层面充分的利用硬件多核cpu不断提升的性能和 在系统界别软件开发上&#xff0c;C出生比较早&#xff0c;内…...

embed mongodb 集成spring

在property文件下添加 de.flapdoodle.mongodb.embedded.version5.0.5 spring.mongodb.embedded.storage.oplog-size0不指定数据库&#xff0c;会使用test&#xff0c; port默认是0&#xff0c;随机端口号。 oplog-size mac默认是192mb, 其他系统会使用5%的磁盘可用空间&#x…...

ssh远程连接服务器

一、远程连接服务器简介 二、连接加密技术简介 三、ssh服务配置 四、用户登录ssh服务 Enforcing会强制限制&#xff0c;如端口为22&#xff0c;可以访问&#xff0c;如果是2000端口&#xff0c;不能使用 Permissive是宽容的模式&#xff0c;不限制使用端口 Enforcing会重启失败…...

性能分析之MySQL慢查询日志分析(慢查询日志)

一、背景 MySQL的慢查询日志是MySQL提供的一种日志记录,他用来记录在MySQL中响应的时间超过阈值的语句,具体指运行时间超过long_query_time(默认是10秒)值的SQL,会被记录到慢查询日志中。 慢查询日志一般用于性能分析时开启,收集慢SQL然后通过explain进行全面分析,一…...

每日一练 | mongo集群如何创建分片键

文章目录 MongoDB是什么什么是分片键环境如何设置分片键 MongoDB是什么 MongoDB 是一个基于分布式文件存储的数据库 什么是分片键 分片&#xff1a;每个分片包含分片数据的一部分。每个分片可以部署为副本集。 而分片键的作用就是把数据按一定的条件分布到各个分片中&#…...

Postman

Postman 简介下载安装 简介 Postman 是一款用于测试和开发 API&#xff08;应用程序编程接口&#xff09;的工具&#xff0c;它提供了用户友好的界面和丰富的功能&#xff0c;帮助开发者轻松地创建、测试、调试和文档化各种类型的 API。无论是在构建 Web 应用、移动应用还是其…...

chapter 3 Free electrons in solid - 3.1 自由电子模型

3.1 自由电子模型 Free electron model 研究晶体中的电子&#xff1a; 自由电子理论&#xff1a;不考虑离子实能带理论&#xff1a;考虑离子实&#xff08;周期性势场&#xff09;的作用 3.1.1 德鲁德模型 Drude Model - Classical Free Electron Model (1)德鲁德模型 德鲁…...

搭建博客时前端美化内容CSS推荐

一、背景 在搭建博客的时候&#xff0c;发现对其markdown文章内容进行渲染的时候&#xff0c;样式调整比较花费时间 二、解决思路 自己适配样式 缺点&#xff1a;ROI不高 使用开源的markdown的样式&#xff1a;github-markdown-css 三、实现教程 1、NPM安装 npm install …...

Linux中 socket编程中多进程/多线程TCP并发服务器模型

一、循环服务器(while)【不常用】 一次只能处理一个客户端的请求&#xff0c;等这个客户端退出后&#xff0c;才能处理下一个客户端。缺点&#xff1a;循环服务器所处理的客户端不能有耗时操作。 模型 sfd socket(); bind(); listen(); while(1) {newfd accept();while(1){r…...

【内网穿透】如何实现在外web浏览器远程访问jupyter notebook服务器

文章目录 前言1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 前言 Jupyter Notebook&#xff0c;它是一个交互式的数据科学和计算环境&#xff0c;支持多种编程语言&#xff0c;如…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...