1、NameServer架构设计
Broker服务器启动后向NameServer集群注册。生产者发送消息时从NameServer获取Broker节点列表信息,根据负载均衡算法选择一个节点发送消息。NameServer与每个Broker节点保持长连接,每间隔10秒检测Broker节点是否存活,如果发现节点宕机则需将故障节点从NameServer的路由注册表中剔除。为了降低NameServer的实现的复杂度,节点的路由变化不会及时同步至生产者,因此消息发送端需要进行容错。
NameServer的高可用是通过部署多台服务器节点实现的。节点之间独立运行互不通信,可能会导致各个节点之间的路由注册信息会有不同,导致某一时刻消息发送的不均衡,但是相对于NameServer的实现的复杂度而言可以忽略。
2、NameServer路由注册&故障剔除
2.1、路由元信息
topicQueueTable:topic消息队列路由表,消息发送通过路由表进行负载均衡
{
"topic1": [{
"brokerName": "broker-a",
"readQueueNums": 10,
"writeQueueNums": 10,
"perm": 6,
"topicSyncFlag": 0
}, {
"brokerName": "broker-b",
"readQueueNums": 10,
"writeQueueNums": 10,
"perm": 6,
"topicSyncFlag": 0
}]
}
brokerAddrTable:broker信息表,包括brokerName、所属集群、主备broker地址列表
{
"broker-a": {
"clusterName": "C1",
"brokerName": "broker-a",
"brokerAddrs": [0: "192.168.1.1:9876", 1: "192.168.1.2:9876"]
},
"broker-b": {
"clusterName": "C1",
"brokerName": "broker-b",
"brokerAddrs": [0: "192.168.1.3:9876", 1: "192.168.1.4:9876"]
}
}
clusterAddrTable:集群信息表,存储集群中所有的brokerName
{
"C1": ["broker-a", "broker-b"]
}
brokerLiveTable:broker状态信息,NameServer收到心跳包后会更新broker信息
{
"192.168.1.2": {
"lastUpdateTimestamp": "1234566776788",
"dataVersion": versionObj,
"channel": channelObj,
"haserverAddr": "192.168.4.3:9999"
}
}
filterServerTable:broker的消息过滤器,用于类消息过滤
2.2、路由注册
RocketMQ的broker的路由注册是通过各节点向NameServer发送心跳包实现的。broker每30s遍历NameServer列表依次向NameServer发送心跳包,NameServer收到心跳包后更新brokerLiveTable的对应的broker的lastTimeUpdateTimestamp。NameServer每10s是扫描一次brokerLiveTable,超过120s未收到心跳包的broker则会移除相应的路由信息,然后关闭和broker的socket长连接。
心跳包主要包含以下内容:brokerAddr、brokerId、brokerName、clusterName、haServerAddr、requestBody。其中haServerAddr指的是主节点地址,初次注册时该值为空,从节点向NameServer注册后返回;reuquestBody主要包含topicConfigWrapper主题配置和filterServerList消息过滤服务器列表。
NameServer处理心跳包的过程如图:
2.3、路由删除
RocketMQ执行路由删除的触发点有两个:
- NameServer扫描brokerLiveTable,超过120s未收到心跳包
- broker正常关闭则会执行unregisterBroker命令
路由删除流程如图:
2.4、路由发现
RocketMQ路由发现并不是实时的,当topic路由信息发生改变时,NameServer不会主动通知生产者和消费者,而是由各个客户端每隔30s拉取路由信息。拉取topic路由信息结果包含以下几个属性:
- orderTopicConf,顺序消息配置内容
- queueDatas,topic相关的队列元数据
- brokerDatas,topic分布的Broker元数据
- filterServerTable,Broker的消息过滤器地址列表
路由发现的流程:
- 调用RouteInfoManager,获取路由表topicQueueTable、brokerAddrTable、filterServerTable用来填充路由结果的queueDatas、brokerDatas、filterServerTable;
- 如果当前topic位顺序消息,则需从NameServer的KV config中获取顺序消息配置填充orderTopicConf;
- 如果未发现当前topic路由信息,则返回TOPIC_NOT_EXISTS