RocketMQ 路由中心

深入解析RocketMQ中NameServer的功能,作为消息队列的状态服务器,NameServer如何存储Broker、Topic等信息,以及如何通过心跳机制实现路由注册和删除,确保消息系统的高可用性和故障延迟通知机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NameServer 的功能

NameServer是整个消息队列中的状态服务器,集群的各个组件通过它来了解全局的信息。同时,各个角色的机器都要定期向NameServer上报自己的状态,超时不上报的话,NameServer会认为某个机器出故障不可用了,其他的组件会把这个机器从可用列表里移除。
NamServer可以部署多个,相互之间独立,其他角色同时向多个NameServer机器上报状态信息,从而达到热备份的目的。NameServer本身是无状态的,也就是说NameServer中的Broker、Topic等状态信息不会持久存储,都是由各个角色定时上报并存储到内存中的(NameServer支持配置参数的持久化,一般用不到)。

NameServer 的存储结构

NameServer 保存了五个变量。

  • topicQueueTable:topic 消息队列路由信息。每一个主题对应一个QueueData,其中的属性包括:brokerName, readQueueNums, writeQueueNums,perm,topicSynFlag
  • brokerAddrTable:broker 基础信息,包含 brokerName、所属集群名称、主备 Broker 地址
  • clusterAddrTable:broker 集群信息,存储集群中所有 broker 名称
  • brokerLiveTable:broker 状态信息。NameServer 每次收到心跳包时会替换该信息
  • filterServerTable:过滤服务器列表

RocketMQ 基于订阅发布机制, 一个 Topic 拥有多个消息队列 ,一个Broker 为每一主题默 认创建 4 个读队列 4 个写队列 。 多个 Broker 组成 一个集群 , BrokerName 由相同的多台 Broker 组 成 Master-Slave 架构 , brokerId 为 0 代表 Master, 大于 0 表示 Slave。 BrokerLivelnfo 中 的 lastUpdateTimestamp 存储上次收到 Broker 心跳包的时间 。

路由注册

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

RocketMQ 的网络传输基于 Netty,每一个请求,RocketMQ 都会定义一个 RequestCode,然后在服务端会有对应的 Processor。

1.发送心跳包

broker 发送的心跳包有以下内容:

  • brokerAddr:broker 地址
  • brokerId:0 表示 master,大于 0 表示 slave
  • brokerName:broker 名称
  • clusterName:集群名称
  • haServerAddr:master 地址,除此请求时该值为空,slave 向 NameServer 注册后返回。
  • requestBody
    • filterServerList。消息过滤服务器列表
    • topicConfigWrapper。主题配置,topicConfigWrapper 内部封装的是 TopicConfig­Manager 中的 topicConfigTable,内部存储的是 Broker启动时默认的一些Topic, MixAll.SELF TEST_TOPICMixAll.DEFAULT_TOPIC ( AutoCreateTopic- Enable=true ), MixAll.BENCHMARK_TOPICMixAll.OFFSET_MOVED_EVENTBrokerConfig#brokerClusterNameBrokerConfig#brokerName
      该配置文件默认存储在:${Rocket_Home}/store/confg/topic.json中。

2.接收心跳包

NameServer 会解析请求类型为RequestCode.REGISTER_BROKER类型的请求,并交由RouteInfoManager处理。
首先判断集群是否存在,然后将 broker 加入到集群集合中。然后更新维护BrokerData 信息,直接替换原来的。如果 Broker 为 master,并且 Broker Topic 配置信息发生变化或者是除此注册,则需要创建或更新 Topic 路由元数据,填充 topicQueueTable。在初次发送心跳包时,就是为默认主题注册路由信息,包含MixAll.DEFAULT_TOPIC的路由信息。当消息生产者发送主题时,如果该主题未创建并且BrokerConfigautoCreateTopicEnable为 true 时,将返回它的路由信息。

路由注册时需要加写锁,防止并发修改RouteInfoManager中的路由表。更新路由表使用了锁粒度较小的读写锁,允许多个消息发送者并发读,保证消息发送时的高并发。但同一时刻 NameServer 只处理一个 Broker 心跳包,多个心跳包请求串行执行。

路由删除

RocketMQ 有两个触发点来触发路由删除。
1.NameServer 定时扫描brokerLiveTable检测上次心跳包与当前系统时间的时间差,如果时间大于 120s,则需要移除该 Broker 信息
2.Broker 在正常被关闭的情况下,执行 unregisterBroker 指令

路由发现

客户端定时拉取主题最新的路由。发现过程:

1.调用 RouterlnfoManager 的方法,从路由表 topicQueueTablebrokerAddrTablefilterServerTable中分别填充TopicRouteData中的List<QueueData>List<BrokerData>filterServer 地址表 。
2.如果找到主题对应的路由信息并且该主题为顺序消息,则从 NameServer KVconfig 中获取关于顺序消息相关 的配置填充路由信息 。

Q & A

RocketMQ 的路由中心存储的是什么数据

见 NameServer 存储结构。

如何避免 NameServer 的单点故障,提供高可用性

启动多个 NameServer,让每个 broker 向每个 NameServer 发送心跳包。

为何不使用 ZooKeeper

ZooKeeper的功能很强大,包括自动Master选举等,RocketMQ的架构设计决定了它不需要进行Master选举,用不到这些复杂的功能,只需要一个轻量级的元数据服务器就足够了。

中间件对稳定性要求很高,RocketMQ的NameServer只有很少的代码,容易维护,所以不需要再依赖另一个中间件,从而减少整体维护成本。
u

为什么 NameServer 的路由变化不会立即通知生产者

为了降低 NameServer 实现的复杂性,在消息发送端提供容错机制来保证消息发送的高可用性。(故障延迟机制)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值