前言
发送消息之前rocketMQ需要获取目的topic的路由信息,即需要将消息发送到哪个topic上
DefaultMQProducerImpl#tryToFindTopicPublishInfo
从缓存中获取topic路由信息,获取到有效路由直接返回,如果没获取到或者获取到的路由信息不可用,则向nameserver查询该topic的路由信息
private TopicPublishInfo tryToFindTopicPublishInfo(final String topic) {
// 从topicPublishInfoTable中获取指定主题的发布信息
TopicPublishInfo topicPublishInfo = this.topicPublishInfoTable.get(topic);
// 如果获取到的发布信息为空,或者发布信息不可用,则进行以下操作
if (null == topicPublishInfo || !topicPublishInfo.ok()) {
// 使用putIfAbsent方法向topicPublishInfoTable中添加一个新的主题发布信息对象
this.topicPublishInfoTable.putIfAbsent(topic, new TopicPublishInfo());
// 调用mQClientFactory.updateTopicRouteInfoFromNameServer方法从名称服务器更新主题的路由信息
this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic);
// 再次尝试从topicPublishInfoTable中获取指定主题的发布信息
topicPublishInfo = this.topicPublishInfoTable.get(topic);
}
// 如果获取到的发布信息具有主题路由信息,或者发布信息可用,则直接返回获取到的发布信息
if (topicPublishInfo.isHaveTopicRouterInfo() || topicPublishInfo.ok()) {
return topicPublishInfo;
} else {
// 尝试用默认主题查询(topic = TBW102)
this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic, true, this.defaultMQProducer);
// 再次尝试从topicPublishInfoTable中获取指定主题的发布信息,并返回获取到的发布信息
topicPublishInfo = this.topicPublishInfoTable.get(topic);
return topicPublishInfo;
}
}
MQClientInstance#updateTopicRouteInfoFromNameServer
如果isDefault == true
,则代表获取默认主题的路由信息,并根据配置更写读写队列的数量,因为defaultMQProducer.getDefaultTopicQueueNums()为4,所以这里结队列数量是4,再加上broker之间数据是各自独立的,所以这里容易出现负载不均衡的情况。(详见https://www.cnblogs.com/dingwpmz/p/11809404.html)