一、NameServer

86 阅读3分钟

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执行路由删除的触发点有两个:

  1. NameServer扫描brokerLiveTable,超过120s未收到心跳包
  2. broker正常关闭则会执行unregisterBroker命令

路由删除流程如图:

2.4、路由发现

        RocketMQ路由发现并不是实时的,当topic路由信息发生改变时,NameServer不会主动通知生产者和消费者,而是由各个客户端每隔30s拉取路由信息。拉取topic路由信息结果包含以下几个属性:

  • orderTopicConf,顺序消息配置内容
  • queueDatas,topic相关的队列元数据
  • brokerDatas,topic分布的Broker元数据
  • filterServerTable,Broker的消息过滤器地址列表

路由发现的流程:

  1. 调用RouteInfoManager,获取路由表topicQueueTable、brokerAddrTable、filterServerTable用来填充路由结果的queueDatas、brokerDatas、filterServerTable;
  2. 如果当前topic位顺序消息,则需从NameServer的KV config中获取顺序消息配置填充orderTopicConf;
  3. 如果未发现当前topic路由信息,则返回TOPIC_NOT_EXISTS