예제 #1
0
  public String findBrokerAddrByTopic(final String topic) {
    TopicRouteData topicRouteData = this.topicRouteTable.get(topic);
    if (topicRouteData != null) {
      List<BrokerData> brokers = topicRouteData.getBrokerDatas();
      if (!brokers.isEmpty()) {
        BrokerData bd = brokers.get(0);
        return bd.selectBrokerAddr();
      }
    }

    return null;
  }
예제 #2
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);
 }
예제 #3
0
  private boolean isBrokerAddrExistInTopicRouteTable(final String addr) {
    Iterator<Entry<String, TopicRouteData>> it = this.topicRouteTable.entrySet().iterator();
    while (it.hasNext()) {
      Entry<String, TopicRouteData> entry = it.next();
      TopicRouteData topicRouteData = entry.getValue();
      List<BrokerData> bds = topicRouteData.getBrokerDatas();
      for (BrokerData bd : bds) {
        if (bd.getBrokerAddrs() != null) {
          boolean exist = bd.getBrokerAddrs().containsValue(addr);
          if (exist) return true;
        }
      }
    }

    return false;
  }
예제 #4
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;
  }
예제 #5
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;
  }
예제 #6
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;
  }
예제 #7
0
  public TopicRouteData pickupTopicRouteData(final String topic) {
    TopicRouteData topicRouteData = new TopicRouteData();
    boolean foundQueueData = false;
    boolean foundBrokerData = false;
    Set<String> brokerNameSet = new HashSet<String>();
    List<BrokerData> brokerDataList = new LinkedList<BrokerData>();
    topicRouteData.setBrokerDatas(brokerDataList);

    HashMap<String, List<String>> filterServerMap = new HashMap<String, List<String>>();
    topicRouteData.setFilterServerTable(filterServerMap);

    try {
      try {
        this.lock.readLock().lockInterruptibly();
        List<QueueData> queueDataList = this.topicQueueTable.get(topic);
        if (queueDataList != null) {
          topicRouteData.setQueueDatas(queueDataList);
          foundQueueData = true;

          // BrokerName去重
          Iterator<QueueData> it = queueDataList.iterator();
          while (it.hasNext()) {
            QueueData qd = it.next();
            brokerNameSet.add(qd.getBrokerName());
          }

          for (String brokerName : brokerNameSet) {
            BrokerData brokerData = this.brokerAddrTable.get(brokerName);
            if (null != brokerData) {
              BrokerData brokerDataClone = new BrokerData();
              brokerDataClone.setBrokerName(brokerData.getBrokerName());
              brokerDataClone.setBrokerAddrs(
                  (HashMap<Long, String>) brokerData.getBrokerAddrs().clone());
              brokerDataList.add(brokerDataClone);
              foundBrokerData = true;

              // 增加Filter Server
              for (final String brokerAddr : brokerDataClone.getBrokerAddrs().values()) {
                List<String> filterServerList = this.filterServerTable.get(brokerAddr);
                filterServerMap.put(brokerAddr, filterServerList);
              }
            }
          }
        }
      } finally {
        this.lock.readLock().unlock();
      }
    } catch (Exception e) {
      log.error("pickupTopicRouteData Exception", e);
    }

    if (log.isDebugEnabled()) {
      log.debug("pickupTopicRouteData {} {}", topic, topicRouteData);
    }

    if (foundBrokerData && foundQueueData) {
      return topicRouteData;
    }

    return null;
  }