路由发现
上篇讲到 路由信息在 namesrv 上注册好了,没有客户端使用怎么行呢。
rocketmq 的 namesrv 不会主动推送topic 的路由到客户端,而是由客户端主动拉取最新的路由信息。这里有一个问题:客户端会在哪些情况下去 namesrv 拉取路由信息,并且拉取的topic 路由信息是陈旧时,如何切换 namesrv 去重新拉取呢?producer 分析见
客户端一般是按照使用的 topic 去拉取的,请求的消息类型为RequestCode.GET_ROUTEINFO_BY_TOPIC
,主要的实现类在RouteInfoManager#pickupTopicRouteData
类中。获取结果为TopicRouteData
对象,其包括如下内容:
private String orderTopicConf; //顺序消息配置信息,存放在 KVConfig 中
private List<QueueData> queueDatas; // topic 的massage Queue
private List<BrokerData> brokerDatas; //topic 所在的 broker数据
private HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable; //消息过滤服务器地址列表
具体消息的获取代码摘录摘录如下:
public TopicRouteData pickupTopicRouteData(final String topic) {
TopicRouteData topicRouteData = new TopicRouteData();
//... 其他topicRouteData子对象的初始化
try {
try {
this.lock.readLock().lockInterruptibly();
//获取 topic 的 message Queue
List<QueueData> queueDataList = this.topicQueueTable.get(topic);
if (queueDataList != null) {
topicRouteData.setQueueDatas(queueDataList);
foundQueueData = true;
Iterator<QueueData> it = queueDataList.iterator();
while (it.hasNext()) {
QueueData qd = it.next();
//依次添加Queue 上 所有的 brokerName
brokerNameSet.add(qd.getBrokerName());
}
//再根据brokerName 获取 broker 地址信息以及消息过滤器
for (String brokerName : brokerNameSet) {
BrokerData brokerData = this.brokerAddrTable.get(brokerName);
if (null != brokerData) {
BrokerData brokerDataClone = new BrokerData(brokerData.getCluster(), brokerData.getBrokerName()