RocketMQ NameServer源码剖析

深入剖析RocketMQ源码-NameServer 一、RocketMQ架构简介 1.1 逻辑部署图 (图片来自网络) 1.2 核心组件说明 通过上图可以看到,RocketMQ的核心组件主要包括4个,分别是NameServer、Broker、Producer和Consumer,下面我们先依次简单说明下这四个核心组件: NameServer:NameServer充当路由信息的提供者。生产者或消费者能够通过NameServer查找各Topic相应的Broker IP列表。多个Namesrver实例组成集群,但相互独立,没有信息交换。 Broker 阅读详情

概述

NameServer是一个简单的 Topic 路由注册中心,支持 Topic、Broker 的动态注册与发现。

主要包括两个功能:

  • Broker管理 ,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活;
  • 路由信息管理 ,每个NameServer将保存关于 Broker 集群的整个路由信息和用于客户端查询的队列信息。Producer和Consumer通过NameServer就可以知道整个Broker集群的路由信息,从而进行消息的投递和消费。

Broker集群、Producer集群、Consumer集群都需要与NameServer集群进行通信。

1、Producer集群

Producer集群和NameServer集群中的随机一台建立⻓连接,得知当前要发送的 Topic 存在哪台BrokerMaster上,然后再与其建立⻓连接,支持多种负载平衡模式发送消息。

注意:消息的生产者,通过NameServer集群获得Topic的路由信息,包括Topic下面有哪些Queue,这些Queue分布在哪些Broker上等。Producer只会将消息发送到Master节点上,因此只需要与Master节点建立连接。

2、Consumer集群

它会先和 NameServer 集群中的随机一台建立⻓连接,得 知当前要消费的 Topic 存在哪台 BrokerMaster、Slave上,然后它们建立⻓连接,支持集群消费和广播消费消息。

消息的消费者,通过NameServer集群获得Topic的路由信息,连接到对应的Broker上消费消息。注意,由于Master和Slave都可以读取消息,因此Consumer会与Master和Slave都建立连接。

3、Broker集群

Broker作用:

  1. 接收生产者发送消息,或者消费者消费消息的请求。
  2. 主要负责消息的存储、转发、查询,支持主从部署,一个 Master 可以对应多个 Slave,Master 支持读写,Slave 只支持读。

一个Broker集群由多组Master/Slave组成,Master可写可读,Slave只可以读,Master将写入的数据同步给Slave。

Broker 会向集群中的每一台 NameServer 注册自己的路由信息。每个Broker节点,在启动时,都会遍历NameServer列表,与每个NameServer建立长连接,注册自己的信息,之后定时上报。

4、NameServer集群

Topic 路由注册中心,支持 Broker 的动态注册和发现,保存 Topic 和 Borker之间的关系。

通常是集群部署,但是各 NameServer 之间不会互相通信, 各 NameServer 都有完整的 路由信息

总结:NameServer 相当于一个NettyServer,处理客户端的请求。RocketMQ学习源码之前最好了解一下Netty和NIO通信的基本流程。

NameServer主要功能

1、代码模块

主要有3个模块, kvconfig 数据存储,processor 通信处理模块, routeinfo 路由模块

  • kvconfig 模块 核心类KVConfigManager作用是,加载namesrvController指定的kvConfig配置文件(常xxx/kvConfig.json)到内存,读取或增加,删除kvConfig记录,将内存记录的配置,持久化到文件打印所有kvConfig配置。

  • processor 模块 DefaultRequestProcessor 处理client发过来的各种请求,比如kv 的crud,注册元数据,读取元数据

  • routeinfo 路由模块 RouteInfoManager 存储一些核心元数据

  1. brokerAddrTable 保存 Topic 的队列信息,也是真正的路由信息。队列信息中包含了其所在的 Broker 名称和读写队列数量。
  2. topicQueueTable 保存 Broker 信息,包含其名称、集群名称、主备 Broker 地址。
  3. clusterAddrTable 保存 Cluster信息,包含每个集群中所有的 Broker 名称列表
  4. brokerLiveTable 活跃Broker映射表,Broker 状态信息,包含当前所有存活的 Broker,和它们最后一次上报心跳的时间。
  5. filterServerTable Broker 上的 FilterServer 列表,用于类模式消息过滤,该机制在 4.4 版本后被废弃。

上面的这些数据都是存储为HashMap保存的内存中,不会做持久化操作。

2、NameServer启动流程

NamesrvStartup 启动类, 逻辑并不复杂,主要是下面两个主要功能。

(1)解析配置文件

填充NameServerConfig、NettyServerConfig属性值。包括:端口号,目录路径,netty线程池个数,消息请求并发度等。

(2) 根据启动属性,创建NamesrvController实例,并初始化该实例。NameServerController为nameServer的核心控制器。

NameServerController里面有一个nettyServer和两个定时任务。

  • nettyServer负责与broker、生产者、消费者进行网络通信
  • 定时任务1:每隔10s扫描一次broker,移除死亡状态broker。
  • 定时任务2:每隔10分钟打印一次KV配置。

3、路由注册

RocketMQ采取的策略是,在Broker节点在启动的时候,轮询NameServer列表,

(1)Broker与每个NameServer节点建立长连接,发起注册请求。

(2)Broker节点为了证明自己是存活的,会将最新的信息上报给NameServer,然后每隔30秒向NameServer发送心跳包。

心跳包中包含 BrokerId、Broker名称、Broker地址、Broker所属集群名称等等。

NameServer独立管理自己的Broker元数据副本:

(1)每个NameServer内部会维护一个Broker表,用来动态存储Broker的信息。

(2)然后NameServer接收到心跳包后,会更新时间戳,记录这个Broker的最新存活时间

路由注册的两个场景:

  • 启动注册:Broker与每个NameServer节点建立长连接,发起注册请求
  • 定时心跳:每隔30秒向NameServer发送心跳包

设计的亮点:

NameServer的性能优化:

为了提升并发修改Broker表的性能,路由注册操作引入了 ReadWriteLock 读写锁,这个设计亮点允许多个消息生产者并发读,保证了消息发送时的高并发,同一时刻NameServer只能处理一个Broker心跳包,多个心跳包串行处理。

这也是读写锁的经典使用场景,即读多写少。

4、路由剔除

NameServer路由剔除的两个场景:

  • 主动剔除场景:Broker在正常关闭的情况下,会执行unregisterBroker指令
  • 被动剔除场景:NameServer定期扫描brokerLiveTable检测上次心跳包与当前系统的时间差,如果时间超过120s,则需要移除broker。

3.1 主动剔除的场景

nameServer与broker保持长连接。

正常情况下,如果Broker关闭,则会与NameServer断开长连接,Netty的通道关闭监听器会监听到连接断开事件,然后会将这个Broker信息剔除掉。

对于一些日常运维工作,例如:Broker升级,RocketMQ提供了一种优雅剔除路由信息的方式。

如在升级一个节Master点之前,可以先通过命令行工具,禁止这个Broker的写权限:

客户端producer 发送消息到这个Broker的请求,都会收到一个NO_PERMISSION响应,客户端会自动重试其他的Broker。

当观察到这个broker没有流量后,再将这个broker移除。

3.2 被动剔除的场景

rocketMq的路由注册是通过broker与NameServer的心跳功能实现的。

broker启动的时候,向集群中的所有nameServer发送心跳,每间隔30秒,向所有的NameServer发送心跳。

nameServer收到心跳包时会更新brokerLiveTable缓存中的lastUpdateTimestamp。然后nameServer每10秒扫描一次brokerLiveTable,如果连续120s没有收到心跳包,判死刑,nameServer将移除该Broker的路由信息,同时关闭nettysocket连接。

被动剔除下,NameServer中有一个定时任务, 每隔 10秒扫描一下Broker表,如果某个Broker的心跳包最新时间戳距离当前时间超多120秒,也会判定Broker失效并将其移除。

5、路由发现

路由发现是客户端的行为,这里的客户端主要说的是生产者和消费者。

主动刷新场景:

(1)对于生产者,在发送第一条消息时,才能明确topic,所以会根据Topic获取从NameServer获取路由信息。

(2)对于消费者,订阅的Topic一般是固定的,所在在启动时就会拉取。

被动刷新的场景:

定时刷新机制

6、客户端NameServer选择策略

RocketMQ会将用户设置的NameServer列表会设置到 NettyRemotingClient类的namesrvAddrList字段中,NettyRemotingClient是RocketMQ对Netty进行了封装,如下:

具体选择哪个NameServer,也是使用round-robin的策略。需要注意的是,尽管使用round-robin策略,但是在选择了一个NameServer节点之后,后面总是会优先选择这个NameServer,除非与这个NameServer节点通信出现异常的情况下,才会选择其他节点。

为什么客户端不与所有NameServer节点建立连接呢,而是只选择其中一个?

通常NameServer节点是配置好的,固定的那么几个,但是客户端的数量可能是成百上千,为了减少每个NameServer节点的压力,所以每个客户端节点开始的时候,随机找一个nameserver建立连接,后面round-robin与其中一个NameServer节点建立连接。

为了尽可能保证NameServer集群每个节点的负载能相对均衡,在round-robin策略选择时,每个客户端的初始随机位置都不同。

NettyRemotingClient#namesrvIndex

private final AtomicInteger namesrvIndex = new AtomicInteger(initValueIndex()); 
private static int initValueIndex() {
    Random r = new Random();
    return Math.abs(r.nextInt() % 999) % 999;
}
复制代码

之后每次选择NameServer时,namesrvIndex+1之后,对namesrvAddrList取模,计算在数据下标的位置,尝试创建连接,一旦创建成功,会将当前选择的NameServer地址记录到namesrvAddrChoosed字段中:

private final AtomicReference<String> namesrvAddrChoosed = new AtomicReference<String>();
复制代码

如果某个NameServer节点创建连接失败是,会自动重试其他节点。

NettyRemotingClient#getAndCreateNameserverChannel

7、NameServer的CAP特征:是AP不是CP?

那么为什么rocketmq选择自己开发一个NameServer,而不是使用这些开源组件呢?

事实上,在RocketMQ的早期版本,即MetaQ 1.x和MetaQ 2.x阶段,也是依赖Zookeeper的。但MetaQ 3.x(即RocketMQ)却去掉了ZooKeeper依赖,转而采用自己的NameServer。

而RocketMQ的架构设计决定了:

nameserver只需要一个轻量级的元数据服务器就足够了nameserver只需要保持最终一致,而不需要Zookeeper这样的强一致性解决方案,不需要再依赖另一个中间件,从而减少整体维护成本。

对于Zookeeper、Etcd这样强一致性组件,数据只要写到主节点,内部会通过状态机将数据复制到其他节点,

Zookeeper使用的是Zab协议,etcd使用的是raft协议。

但是:NameServer节点之间是互不通信的,无法进行数据复制。

RocketMQ-RocketMQ⾼性能核心原理与源码剖析(上) 实际上,在应用中,可以通过producer.setSendMessageWithVIPChannel(true),让少量比较重要的producer走VIP的通道。这个Cotroller对象就跟MVC中的Controller是很类似的,都是响应客户端的请求。我们现在不需要了解这些核心组件的具体功能,只要有个大概,Broker中有一大堆的功能组件负责具体的业务。​ 从NameServer启动和关闭这两个关键步骤,我们可以总结出NameServer的组件其实并不是很多,整个NameServer的结构是这样的; 阅读详情

相关推荐

DIC新手避坑指南:压缩实验中的应变测量常见错误与数据校验技巧

本文为DIC技术新手提供了压缩实验中应变测量的全面避坑指南。文章系统梳理了从试样尺寸录入、散斑质量到数据后处理中应变方向与符号混淆、数据插值对齐等常见错误,并分享了基于MATLAB的自动化数据校验与可视化对比技巧,帮助建立可靠的实验数据分析SOP,确保DIC测量结果的准确性。

weixin_29313423的博客 113

RcoketMQ 全部配置表

1、Broker配置 参数名 默认值 说明 listenPort 10911 接受客户端连接的监听端口 namesrvAddr null nameServer 地址 brokerIP1 网卡的 InetAddress 当前 broker 监听的 IP brokerIP2 跟 brokerIP1 一样 存在主从 bro..

Xx__WangQi的博客 657

从实验室到生活:构建一份全面的手机相机主观画质评测指南

本文详细介绍了如何从实验室数据转向实际体验,构建全面的手机相机主观画质评测指南。通过基础装备清单、室内外场景实战评测及数据之外的感知艺术,帮助用户发现手机相机在色彩还原、动态范围和夜景模式等方面的真实表现。特别关注主观体验与客观参数的差异,提供实用的评测技巧和报告撰写心法。

weixin_30940783的博客 308

Rocketmq之NameServer地址配置及更新

NameServer在整个Rocketmq的模块划分中占据重要的地位,起到类似于注册中心的作用。BrokerServer启动时需要向NameServer注册自身元数据信息以及主题Topic信息,而Producer发送消息到BrokerServer、Consumer从BrokerServer订阅消息,则需要经过NameServer才能确定最终要进行数据通讯的BrokerServer的地址,所以,BrokerServer、Producer、Consumer程序启动均需要配置NameServer的地址。

carbuser_xl的博客 1万+

(Linux)DHCP 超级作用域和中继代理(超难受做了超久)

DHCP服务器在192.168.159.0 可以实现分配IP的功能,现在要跨网段分配IP 就需要用到DHCP中继代理。中继代理有两张网卡分别eth0:IP 192.168.159.2 ;eth1: IP:192.168.200.2 。现在要实现192.168.200.0网段的客户机可以获取DHCP服务器的IP。中继代理其实是相当于一个路由器的作用 DHCP服务器的IP地址 :192.168.159...

DJ_joker的博客 2225

生存网络与mlr3proba

通过结合生存网络和mlr3proba,可以使用生存网络模型来预测个体在给定时间点发生事件的概率,并使用mlr3proba提供的工具进行模型的训练、评估和选择最佳模型。iii)基本的机器学习(ML)方法,如重新排序和调整。在本文中,我们将只讨论前五种,因为它们在文献中得到了更好的建立,并且它们具有相同的接口,这简化了调优,我们将在下面看到。我们不会为模型指定自定义架构,而是使用默认架构,如果你熟悉PyTorch,那么你可以选择创建自己的架构,如果你愿意的话,通过将其传递给模型中的custom_net参数。

weixin_46587777的博客 1363

RocketMQ5.0.0路由中心NameServer

介绍NameServer的注册中心作用,Broker定时任务发送心跳包给NameServer,NameServer是消息存储Broker、生产者、消费者、从Broker的连接桥梁。

爱我所爱0505 1511

告别第三方插件:官方Fused Library如何重塑Android库的合并与发布流程

本文详细介绍了Android官方推出的Fused Library如何替代第三方fat-aar插件,优化Android库的合并与发布流程。通过原生支持、智能依赖管理等优势,Fused Library解决了版本兼容性、依赖传递等核心痛点,提供了更稳定高效的开发体验。文章还提供了迁移实操指南和工程实践建议,帮助开发者顺利过渡到官方方案。

weixin_42561040的博客 254

【RocketMQ】NameServer总结

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

Gefangenes的博客 429

《遥感大模型生产级实战:从数据到决策的端到端AI工程》系列第一部分:AI遥感工程师的基础设施与工具链-文章 4:传统遥感分析与机器学习基线

本章将系统性地介绍经典遥感分析工作流,从数据预处理到多维度特征工程,再到如何利用经典的机器学习模型(如随机森林、支持向量机)进行监督与非监督学习。我们将通过一个完整的“智慧农业作物分类”项目实战,展示如何利用我们之前构建的数据湖和工具链,从原始数据到最终的分析结果,构建一个性能可靠、可解释性强的基线系统。更重要的是,我们将深入剖析这种传统方法的局限性,从而为后续章节引入遥感大模型的必要性提供强有力的论证。

panshengwu的博客 705

学Simulink--基础微电网场景实例:基于Simulink的微电网并网/孤岛无缝切换控制仿真

本文完成了基于 Simulink 的微电网并网/孤岛无缝切换控制仿真,实现了:✅ 构建含双模式逆变器的微电网模型✅ 实现预同步 + Stateflow 逻辑的智能切换✅ 验证计划与非计划切换的性能边界✅ 证明“无缝”在工程上是可实现的。

amy_mhd的博客 102

RocketMQ源码系列(一) NameServer 核心源码解析

一、NameServer 介绍 二、NameServer 功能列表 三、NameServer 架构分析 四、NameServer 架构

Dream_it_possible!的博客 2万+

语音识别:PyAudio、SoundDevice、Vosk、openai-whisper、Argos-Translate、FunASR(Python)

本文介绍了Python中常用的音频处理库PyAudio,详细解析了其核心功能、核心概念和典型工作流程。PyAudio是一个跨平台的音频I/O库,支持音频录制、播放、实时流处理和低延迟操作。核心概念包括PyAudio类(管理音频设备和流)和Stream类(代表音频流)。文章重点讲解了open()方法的关键参数、回调函数的使用方式以及典型的工作流程,包括设备查询、流配置和资源释放。PyAudio适用于需要实时音频处理的场景,如语音识别和音频效果处理。

算法工程师 706

RocketMQ—NameServer总结及核心源码剖析

​一、NameServer介绍 NameServer 是专为 RocketMQ 设计的轻量级名称服务,具有简单、可集群横向扩展、无状态,节点之间互不通信等特点。整个Rocketmq集群的工作原理如下图所示: ​ 可以看到,RocketMQ架构上主要分为四部分, Broker、Producer、Consumer、NameServer,其他三个都会与NameServer进行通信: NameServer: 一个简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broke

IT巅峰技术专栏 821

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

RocketMQ NameServer 详解 源码剖析

[TOC] 1. 概述 1.1 NameServer 是什么 NameServer 是组成 RocketMQ 的重要组件之一,是除了 Broker 之外另一个需要部署的服务。设想这样一个问题:RocketMQ 的 Topic 分布在不同的 Broker 上,作为消息的生产者和消费者,如何知道要从哪个 Broker 地址生产或消费消息?如果连接的 Broker 宕机了,如何在不重启的情况下感知?NameServer 就是为了解决这些问题设计的。 NameServer 是一个简单的 Topic 路由注册中心,类

金甲虫的博客 1232

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

RocketMQ源码之注册中心NameServer【源码版本:RocketMQ4.6】

hello 大家好,我是还没毕业就有1年工作经验且爱抄中间件代码的路人丙,今天想跟大家分享一下笔者“哪些年 ,抄过的中间件代码”,以及阅读RocketMQ源码剖析之注册中心NameServer的笔记记录。源码版本:RocketMQ4.6

whatjeans的博客 519

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

RocketMQ源码(一) NameServer 启动流程和存储结构剖析

前言 NameServer 作为 RocketMQ 的注册中心,对Broker和路由信息进行管理。那我们带着几个问题去剖析 NameServer 的源码: NameServer 启动流程是什么样的?会创建哪些核心数据结构? NameServer 以什么样的数据结构存储着 Broker 与路由信息的? Broker 上线、下线、发送心跳这些操作在 NameServer 中是如何进行的? NameServer 是如何进行 Broker 心跳检测的? 我们带着上面的这些问题来开始剖析 NameServer 的

不是秃头的程序员小李 998

java版Spring Cloud+SpringBoot+mybatis+uniapp 之深入剖析RocketMQ源码-NameServer

一、RocketMQ架构简介 1.1 逻辑部署图 (图片来自网络) 1.2 核心组件说明 通过上图可以看到,RocketMQ的核心组件主要包括4个,分别是NameServer、Broker、Producer和Consumer,下面我们先依次简单说明下这四个核心组件: NameServer:NameServer充当路由信息的提供者。生产者或消费者能够通过NameServer查找各Topic相应的Broker IP列表。多个Namesrver实例组成集群,但相互独立,没有信息交换。 Broker

m0_61571842的博客 918

RocketMQ整体架构及NameServer源码分析

RocketMQ 是阿里巴巴集团基于高可用分布式集群技术,自主研发的云正式商用的专业消息中间件,既可为分布式应用系统提供异步解耦和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性,是阿里巴巴双 11 使用的核心产品。

weixin_43875870的博客 497

RocketMQ高性能核心原理与源码架构剖析

但是在测试源码中,需要指定NameServer地址。​ 调试时,先在项目目录下创建一个conf目录,并从distribution拷贝broker.conf和logback_broker.xml和logback_namesrv.xml。启动example模块下的org.apache.rocketmq.example.quickstart.Producer类即可发送消息。启动Broker时,同样需要ROCETMQ_HOME环境变量,并且还需要配置一个-c 参数,指向broker.conf配置文件。

不积跬步无以至千里 803

RocketMQ源码(5)—Broker与NameServer的心跳服务源码

详细介绍了RocketMQ的Broker与NameServer的心跳服务源码。

终生学习践行者 1509
上一篇: springBoot异步线程,父子线程数据传递的5种姿势
下一篇: 从源码中理解Spring Boot自动装配原理
程序员职业指南
博客等级 码龄4年 2136粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值