RocketMQ技术内幕:RocketMQ架构设计与实现原理(第2版)
上QQ阅读APP看书,第一时间看更新

2.1 NameServer架构设计

消息中间件的设计思路一般是基于主题的订阅发布机制,消息生产者(Producer)发送某一主题的消息到消息服务器,消息服务器负责该消息的持久化存储,消息消费者(Consumer)订阅感兴趣的主题,消息服务器根据订阅信息(路由信息)将消息推送给消费者(推模式)或者消息消费者主动向消息服务器拉取消息(拉模式),从而实现消息生产者与消息消费者的解耦。为了避免因消息服务器的单点故障导致的整个系统瘫痪,通常会部署多台消息服务器共同承担消息的存储。那么消息生产者如何知道消息要发往哪台消息服务器呢?如果某一台消息服务器宕机了,生产者如何在不重启服务的情况下感知呢?

NameServer就是为了解决上述问题而设计的,RocketMQ的逻辑部署如图2-1所示。

040-1

图2-1 RocketMQ物理部署图

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

NameServer本身的高可用性可通过部署多台NameServer服务器来实现,但彼此之间互不通信。虽然NameServer服务器之间在某一时刻的数据并不会完全相同,但对消息发送不会造成重大影响,无非就是短暂造成消息发送不均衡,这也是RocketMQ NameServer设计的一个亮点。

NameServer核心架构设计如图2-2所示。

041-1

图2-2 NameServer架构设计

消息客户端与NameServer、Broker的交互设计要点如下。

1)Broker每隔30s向NameServer集群的每一台机器发送心跳包,包含自身创建的topic路由等信息。

2)消息客户端每隔30s向NameServer更新对应topic的路由信息。

3)NameServer收到Broker发送的心跳包时会记录时间戳。

4)NameServer每隔10s会扫描一次brokerLiveTable(存放心跳包的时间戳信息),如果在120s内没有收到心跳包,则认为Broker失效,更新topic的路由信息,将失效的Broker信息移除。