Задержка при получении сообщений из темы JMS - PullRequest
2 голосов
/ 21 декабря 2011

У меня есть тема с постоянными подписчиками. Я могу публиковать и принимать сообщения, однако вижу, что при чтении сообщений из темы есть некоторая задержка.

Я не могу прочитать сообщения за один звонок. Мне нужно вызвать метод несколько раз, чтобы прочитать сообщения. Я что-то упустил?

    private void publishMessage() {
        TopicConnection topicConnection = null;
        TopicSession topicSession = null;
        TopicPublisher topicPublisher = null;
        try {
          topicConnection = connectionFactory.createTopicConnection();
          topicSession = topicConnection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
          Topic topicName= topicSession.createTopic(topicName);
          topicPublisher = topicSession.createPublisher(topicName);
          ObjectMessage message = topicSession.createObjectMessage(customObject)
          message.setStringProperty("user", userProperty);
          topicPublisher.publish(message, DeliveryMode.PERSISTENT, Message.DEFAULT_PRIORITY, timeToLive);
        } catch (JMSException e) {
          throw new RuntimeException("Error Sending UMessage", e);
        } finally {
          closeConnections(null, topicPublisher, topicSession, topicConnection);
        }
    }

public void consumeMessages(String userId, int maxResults) {
    TopicConnection topicConnection = null;
    TopicSession topicSession = null;
    TopicSubscriber topicSubscriber = null;

    try {
      topicConnection = connectionFactory.createTopicConnection("guest","guest");
      topicConnection.setClientID("topic");
      topicSession = topicConnection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
      Topic topicName= topicSession.createTopic(topicName);
      topicSubscriber = topicSession.createDurableSubscriber(topicName, "subscriptionname", String.format("user = '%s'", userName), false);
      topicConnection.start();
      Message msg = null;

      do {
        msg = topicSubscriber.receiveNoWait();
        if (msg instanceof ObjectMessage) {
          ObjectMessage om = (ObjectMessage) msg;
         else {
            log.error(String.format(" %s", om.getObject().getClass().getSimpleName()));
          }
        } else if (msg != null) {
          log.error(String.format("e %s", msg.getClass().getSimpleName()));
        }
      } while (msg != null && out.size() <= maxResults);
    } catch (JMSException e) {
      throw new RuntimeException("Error retrieving User Messages", e);
    } finally {
      closeConnections(topicSubscriber, null, topicSession, topicConnection);
    }
    return out;
}

1 Ответ

0 голосов
/ 21 декабря 2011

Вы вызываете receiveNoWait (), который будет получать по одному сообщению за раз.В зависимости от вашего провайдера JMS обычно происходит следующее: клиент JMS извлекает сразу несколько сообщений и кэширует их на стороне клиента, чтобы уменьшить задержку в сети.Когда вы вызываете метод receive, он берет сообщение из этого кэша и передает его вам.

Если вы наблюдаете длительные задержки в минуту, то вы либо ошибаетесь в том, как вы помещаете эти сообщения в тему, либо блокируете получение сообщений во время обработки каждого сообщения.Если вы не хотите блокировать получение сообщений во время обработки, обратите внимание на реализацию интерфейса MessageListener вместо использования методов приема или вы можете получать сообщения из вашего метода приема и обрабатывать их в пуле потоков асинхронно.

Когда вы создаете потребителя, вы можете добавить слушателя следующим образом:

MessageListener listener = new MyListener();
consumer.setMessageListener(listener);

Затем создайте класс для обработки сообщений или реализуйте интерфейс в существующем классе потребителя:

public class MyListener implements MessageListener {
  public void onMessage(Message message)
  {
     TextMessage text = (TextMessage) message;

     System.out.println("Message: " + text.getText());
  }
}
...