学习重点
- NameServer整体架构设计
- NameServer动态路由发现与剔除机制
先看一下 RocketMQ 的物理部署图,NameServer 类似于一个注册中心,生产者、消费者、Broker 都需要直接与 NameServer 进行通信。
Broker 消息服务器在启动时向所有 NameServer 注册,消息生产者(Producer)在发送消息之前先从 NameServer 获取 Broker 服务器地址列表,然后根据负载算法从列表中选择一台消息服务器进行消息发送 NameServer 与每台 Broker 服务器保持长连接,并间隔 30s 检测 Broker 是否存活,如果检测到 Broker 从路由注册表中将其移除但是路由变化不会马上通知消息生产者,为什么要这样设计呢?这是为了降低 NameServer 实现的复杂,在消息发送端提供容错机制来保证消息发送的高可用性。
- topicQueueTable: Topic 消息队列路由信息,消息发送时根据路由表进行负载均衡。
- brokerAddrTable: Broker 基础信息,包含 brokerName、所属集群名称、主备 Broker 地址。
- clusterAddrTable: Broker 集群信息,存储集群中所有 Broker 名称。
- brokerLiveTable: Broker 状态信息,NameServer 每次收到心跳包时会替换该信息。
- filterServerTable : Broker 上的 FilterServer 列表,用于类模式消息过滤。
RocketMQ 路由注册是通过 Broker 与 NameServer 的心跳功能实现的,具体流程如下:
- Broker 启动时向集群中所有的 NameServer 发送心跳包,每隔 30s 向集群中所有NameServer 发送心跳包;
- NameServer 收到 Broker 心跳包时会更新 brokerLiveTable 缓存中 BrokerLiveInfo 的
lastUpdateTimestamp; - NameServer每隔 10s 扫描 brokerLiveTable,如果连续 120s 没有收到心跳包,则移除该 Broker 同时关闭 socket 连接。
设计亮点: NameServer 与 Broker 保持长连接, Broker 状态存储在 brokerLiveTable 中,NameServer 每收到一个心跳包,将更新 brokerLiveTable 中关于 Broker 的状态信息以及路由表( topicQueueTable、brokerAddrTable、brokerLiveTable、filterServerTable 更新上述路由表(HashTable )使用了锁粒度较少的读写锁,允许多个消息发送者(Producer)并发读,保证消息发送时的高并发 但同一时刻 NameServer 只处理一个 Broker 心跳包,多个心跳包请求串行执行 。
路由删除RockteMQ 两个触发点来触发路由删除:
- NameServer 定时扫描 brokerLiveTable 检测上次心跳包与当前系统时间的时间差,如果时间戳大于 120s ,则需要移除该 Broker 信息。
- Broker 在正常被关闭的情况下,会执行 unregisterBroker 指令。
RocketMQ 路由发现是非实时的,当 Topic 路由出现变化后, NameServer 不主动推送给客户端,而是由客户端定时拉取主题最新的路由。
总结主要学习了 NameServer 和 Broker 的路由注册与删除机制,如下图所示:



