消耗来自JMS主题的消息时延迟

时间:2011-12-20 22:26:27

标签: java jms messaging

我有一个持久订阅者的主题。我可以发布和使用消息,但是我发现从主题中读取消息时会有一些延迟。

我无法在一次通话中阅读这些消息。我需要多次调用该方法来阅读消息。我错过了什么吗?

    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 :(得分:0)

您正在调用receiveNoWait(),它将一次检索一条消息。根据您的JMS提供程序,通常会发生的情况是,JMS客户端将立即检索大量消息并将其缓存在客户端以减少网络延迟。当您致电接收时,它会从此缓存中获取消息并将其提供给您。

如果您看到很长时间的延迟,那么您将这些消息放到主题上的方式有问题,或者您在处理每条消息时阻止了您的消息接收。如果您希望在处理过程中不阻止收到消息,请查看实现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());
  }
}