RocketMQ NameServer

简介: 前面我们已经简单地介绍了 RocketMQ 的整体设计思路,本文着重其中 NameServer 部分的实现细节。

引言

前面我们已经简单地介绍了 RocketMQ 的整体设计思路,本文着重其中 NameServer 部分的实现细节,更多关于 RocketMQ 的文章均收录于<RocketMQ系列文章>;

NameServer

本节主要介绍RocketMQ路由管理、服务注册及服务发现的机制,NameServer是整个RocketMQ的“大脑”。相信大家对“服务发现”这个词语并不陌生,分布式服务SOA架构体系中会有服务注册中心,分布式服务SOA的注册中心主要提供服务调用的解析服务,指引服务调用方(消费者)找到“远方”的服务提供者,完成网络通信,那么RocketMQ的路由中心存储的是什么数据呢?作为一款高性能的消息中间件,如何避免NameServer的单点故障,提供高可用性呢?

Broker消息服务器在启动时向所有NameServer注册,消息生产者(Producer)在发送消息之前先从NameServer获取Broker服务器地址列表,然后根据负载算法从列表中选择一台消息服务器进行消息发送。NameServer与每台Broker服务器保持长连接,并间隔30s检测Broker是否存活,如果检测到Broker宕机,则从路由注册表中将其移除。但是路由变化不会马上通知消息生产者,为什么要这样设计呢?这是为了降低NameServer实现的复杂性,在消息发送端提供容错机制来保证消息发送的高可用性。

NameServer本身的高可用可通过部署多台NameServer服务器来实现,但彼此之间互不通信,也就是NameServer服务器之间在某一时刻的数据并不会完全相同,但这对消息发送不会造成任何影响,这也是RocketMQ NameServer设计的一个亮点,RocketMQ NameServer设计追求简单高效。

存储内容

private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
  • topicQueueTable:Topic消息队列路由信息,消息发送时根据路由表进行负载均衡。
  • brokerAddrTable:Broker基础信息,包含brokerName、所属集群名称、主备Broker地址。
  • clusterAddrTable:Broker集群信息,存储集群中所有Broker名称。
  • brokerLiveTable:Broker状态信息,NameServer每次收到心跳包时会替换该信息。
  • filterServerTable:Broker上的FilterServer列表,用于类模式消息过滤。

QueueData、BrokerData、BrokerLiveInfo类图如下图所示。
meta-data
RocketMQ 2主2从部署图如下所示。
2m2s-deploy
对应运行时数据结构如下图所示。
memory-1
memory-2

路由注册

RocketMQ路由注册是通过Broker与NameServer的心跳功能实现的。Broker启动时向集群中所有的NameServer发送心跳语句,每隔30s向集群中所有NameServer发送心跳包,NameServer收到Broker心跳包时会更新brokerLiveTable缓存中BrokerLiveInfo的lastUpdateTimestamp,然后NameServer每隔10s扫描brokerLiveTable,如果连续120s没有收到心跳包,NameServer将移除该Broker的路由信息同时关闭Socket连接。

心跳包

  • brokerAddr:broker地址。
  • brokerId:brokerId,O:Master;大于0:Slave。
  • brokerName:broker名称。
  • clusterName:集群名称。
  • haServerAddr:master地址,初次请求时该值为空,slave向NameServer注册后返回其MasterAddr。
  • requestBody:

    • filterServerList:消息过滤服务器列表。
    • topicConfigWrapper:主题配置。

从心跳包内容我们会发现,每次心跳包中都会包含所有的topic信息,如果一个broker上topic非常多的话,心跳包就会比较大,如果正好赶上网络不好的时候,可能就会导致broker下线。

NameServer与Broker保持长连接,Broker状态存储在brokerLiveTable中,NameServer每收到一个心跳包,将更新brokerLiveTable中关于Broker的状态信息以及路由表(topicQueueTable、 brokerAddrTable、 brokerLiveTable、 filterServerTable)。

路由删除

Broker每隔30s向NameServer发送一个心跳包,心跳包中包含BrokerId、Broker地址、Broker名称、Broker所属集群名称、Broker关联的FilterServer列表。但是如果Broker宕机,NameServer无法收到心跳包,此时NameServer如何来剔除这些失效的Broker呢? NameServer会每隔1Os扫描brokerLiveTable状态表,如果BrokerLive的lastUpdateTimestamp的时间戳距当前时间超过120s,则认为Broker失效,移除该Broker, 关闭与Broker连接,并同时更新topicQueueTable、brokerAddrTable、brokerLiveTable、filterServerTable。

RocketMQ有两个触发点来触发路由删除:

  1. NameServer定时扫描brokerLiveTable检测上次心跳包与当前系统时间的时间差,如果时间戳大于120s,则需要移除该Broker信息。
  2. Broker在正常被关闭的情况下,会执行unRegisterBroker指令,主动删除NameServer中关于自己的信息。

路由发现

RocketMQ路由发现是非实时的,当Topic路由出现变化后,NameServer不主动推送给客户端,而是由客户端定时拉取主题最新的路由。

工作示意图

name-server-work

文章说明

更多有价值的文章均收录于贝贝猫的文章目录

stun

版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

创作声明: 本文基于下列所有参考内容进行创作,其中可能涉及复制、修改或者转换,图片均来自网络,如有侵权请联系我,我会第一时间进行删除。

参考内容

[1]《RocketMQ技术内幕》
[2]《RocketMQ实战与原理解析》
[3] 老生常谈——利用消息队列处理分布式事务
[4] RocketMQ架构解析
[5] MappedByteBuffer VS FileChannel 孰强孰弱?
[6] 文件 IO 操作的一些最佳实践
[7] 海量数据处理之Bloom Filter详解
[8] rocketmq GitHub Wiki

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
7月前
|
消息中间件 存储 负载均衡
RocketMQ 源码分析——NameServer
- 编写优雅、高效的代码。RocketMQ作为阿里双十一交易核心链路产品,支撑千万级并发、万亿级数据洪峰。读源码可以积累编写高效、优雅代码的经验。 - 提升微观的架构设计能力,重点在思维和理念。Apache RocketMQ作为Apache顶级项目,它的架构设计是值得大家借鉴的。 - 解决工作中、学习中的各种疑难杂症。在使用RocketMQ过程中遇到消费卡死、卡顿等问题可以通过阅读源码的方式找到问题并给予解决。 - 在BATJ一线互联网公司面试中展现优秀的自己。大厂面试中,尤其是阿里系的公司,你有RocketMQ源码体系化知识,必定是一个很大的加分项。
126 0
|
消息中间件 RocketMQ
不科学,RocketMQ生产者在一个应用服务竟然不能向多个NameServer发送消息
不科学,RocketMQ生产者在一个应用服务竟然不能向多个NameServer发送消息
210 0
不科学,RocketMQ生产者在一个应用服务竟然不能向多个NameServer发送消息
|
消息中间件 Java RocketMQ
RocketMq Nameserver源码分析-01
RocketMq Nameserver源码分析-01
99 0
|
消息中间件 数据可视化 Java
RocketMq之nameserver源码阅读
RocketMq之nameserver源码阅读
89 0
RocketMq之nameserver源码阅读
|
消息中间件 存储 负载均衡
RocketMQ的路由中心:NameServer源码解析
RocketMQ的路由中心:NameServer源码解析
211 0
RocketMQ的路由中心:NameServer源码解析
|
消息中间件 存储 Java
RocketMQ的NameServer执行流程学习梳理
首先NamesrvStartUp启动,首先经过main()方法,也是我们常见的main方法进入到main0()执行创建controller操作与启动controller操作这两个操作。而创建controller的操作则首先需要拿到namesrvConfig的配置信息和NettyServerConfig的配置信息,此时会 创建这两个对象,并填充配置信息然后放入到创建的controller对象中的构造函数中,并进行controller的启动操作,而启动操作首先会初始化一些信息和添加jvm钩子,也即会进行如下操作:加载键值对配置管理器、创建远程服务器remotingServer,创建远程线程池rem
94 2
RocketMQ的NameServer执行流程学习梳理
|
消息中间件 存储 Java
RocketMQ源码分析-NameServer解析一
开篇先上一张RocketMQ官方的经典架构图,如下图所示:
244 0
RocketMQ源码分析-NameServer解析一
|
消息中间件 Dubbo 应用服务中间件
RocketMQ源码分析1:NameServer启动
NameServer是一个非常简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现。
128 0
|
消息中间件 Java Shell
RocketMQ概念详细之NameServer
NameServer 相关信息
4747 0
|
消息中间件 算法 Java
弥补延时消息的不足,RocketMQ 基于时间轮算法实现了定时消息!
弥补延时消息的不足,RocketMQ 基于时间轮算法实现了定时消息!
609 1
弥补延时消息的不足,RocketMQ 基于时间轮算法实现了定时消息!