Пример #1
0
 private boolean topicRouteDataIsChange(TopicRouteData olddata, TopicRouteData nowdata) {
   if (olddata == null || nowdata == null) return true;
   TopicRouteData old = olddata.cloneTopicRouteData();
   TopicRouteData now = nowdata.cloneTopicRouteData();
   Collections.sort(old.getQueueDatas());
   Collections.sort(old.getBrokerDatas());
   Collections.sort(now.getQueueDatas());
   Collections.sort(now.getBrokerDatas());
   return !old.equals(now);
 }
Пример #2
0
  public static Set<MessageQueue> topicRouteData2TopicSubscribeInfo(
      final String topic, final TopicRouteData route) {
    Set<MessageQueue> mqList = new HashSet<MessageQueue>();
    List<QueueData> qds = route.getQueueDatas();
    for (QueueData qd : qds) {
      if (PermName.isReadable(qd.getPerm())) {
        for (int i = 0; i < qd.getReadQueueNums(); i++) {
          MessageQueue mq = new MessageQueue(topic, qd.getBrokerName(), i);
          mqList.add(mq);
        }
      }
    }

    return mqList;
  }
Пример #3
0
  public static TopicPublishInfo topicRouteData2TopicPublishInfo(
      final String topic, final TopicRouteData route) {
    TopicPublishInfo info = new TopicPublishInfo();
    // 顺序消息
    if (route.getOrderTopicConf() != null && route.getOrderTopicConf().length() > 0) {
      String[] brokers = route.getOrderTopicConf().split(";");
      for (String broker : brokers) {
        String[] item = broker.split(":");
        int nums = Integer.parseInt(item[1]);
        for (int i = 0; i < nums; i++) {
          MessageQueue mq = new MessageQueue(topic, item[0], i);
          info.getMessageQueueList().add(mq);
        }
      }

      info.setOrderTopic(true);
    }
    // 非顺序消息
    else {
      List<QueueData> qds = route.getQueueDatas();
      // 排序原因:即使没有配置顺序消息模式,默认队列的顺序同配置的一致。
      Collections.sort(qds);
      for (QueueData qd : qds) {
        if (PermName.isWriteable(qd.getPerm())) {
          for (int i = 0; i < qd.getWriteQueueNums(); i++) {
            MessageQueue mq = new MessageQueue(topic, qd.getBrokerName(), i);
            info.getMessageQueueList().add(mq);
          }
        }
      }

      info.setOrderTopic(false);
    }

    return info;
  }
Пример #4
0
  /** 调用Name Server接口,根据Topic获取路由信息 */
  public boolean updateTopicRouteInfoFromNameServer(
      final String topic, boolean isDefault, DefaultMQProducer defaultMQProducer) {
    try {
      if (this.lockNamesrv.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) {
        try {
          TopicRouteData topicRouteData;
          if (isDefault) {
            if (null == defaultMQProducer) return false;
            topicRouteData =
                this.mQClientAPIImpl.getTopicRouteInfoFromNameServer(
                    defaultMQProducer.getCreateTopicKey(), 1000 * 3);
            for (QueueData data : topicRouteData.getQueueDatas()) {
              // 读写分区个数是一致,故只做一次判断
              int queueNums =
                  Math.min(defaultMQProducer.getDefaultTopicQueueNums(), data.getReadQueueNums());
              data.setReadQueueNums(queueNums);
              data.setWriteQueueNums(queueNums);
            }
          } else {
            topicRouteData = this.mQClientAPIImpl.getTopicRouteInfoFromNameServer(topic, 1000 * 3);
          }
          if (topicRouteData != null) {
            TopicRouteData old = this.topicRouteTable.get(topic);
            boolean changed = topicRouteDataIsChange(old, topicRouteData);
            if (!changed) {
              changed = this.isNeedUpdateTopicRouteInfo(topic);
            } else {
              log.info(
                  "the topic[{}] route info changed, odl[{}] ,new[{}]", topic, old, topicRouteData);
            }

            if (changed) {
              // 后面排序会影响下次的equal逻辑判断,所以先clone一份
              TopicRouteData cloneTopicRouteData = topicRouteData.cloneTopicRouteData();

              // 更新Broker地址信息
              for (BrokerData bd : topicRouteData.getBrokerDatas()) {
                this.brokerAddrTable.put(bd.getBrokerName(), bd.getBrokerAddrs());
              }

              // 更新发布队列信息
              {
                TopicPublishInfo publishInfo =
                    topicRouteData2TopicPublishInfo(topic, topicRouteData);
                Iterator<Entry<String, MQProducerInner>> it =
                    this.producerTable.entrySet().iterator();
                while (it.hasNext()) {
                  Entry<String, MQProducerInner> entry = it.next();
                  MQProducerInner impl = entry.getValue();
                  if (impl != null) {
                    impl.updateTopicPublishInfo(topic, publishInfo);
                  }
                }
              }

              // 更新订阅队列信息
              {
                Set<MessageQueue> subscribeInfo =
                    topicRouteData2TopicSubscribeInfo(topic, topicRouteData);
                Iterator<Entry<String, MQConsumerInner>> it =
                    this.consumerTable.entrySet().iterator();
                while (it.hasNext()) {
                  Entry<String, MQConsumerInner> entry = it.next();
                  MQConsumerInner impl = entry.getValue();
                  if (impl != null) {
                    impl.updateTopicSubscribeInfo(topic, subscribeInfo);
                  }
                }
              }
              log.info("topicRouteTable.put TopicRouteData[{}]", cloneTopicRouteData);
              this.topicRouteTable.put(topic, cloneTopicRouteData);
              return true;
            }
          } else {
            log.warn(
                "updateTopicRouteInfoFromNameServer, getTopicRouteInfoFromNameServer return null, Topic: {}",
                topic);
          }
        } catch (Exception e) {
          if (!topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)) {
            log.warn("updateTopicRouteInfoFromNameServer Exception", e);
          }
        } finally {
          this.lockNamesrv.unlock();
        }
      } else {
        log.warn("updateTopicRouteInfoFromNameServer tryLock timeout {}ms", LockTimeoutMillis);
      }
    } catch (InterruptedException e) {
      log.warn("updateTopicRouteInfoFromNameServer Exception", e);
    }

    return false;
  }