简体   繁体   English

消费来自JMS主题的消息时出现延迟

[英]Delay while consuming messages from JMS Topic

I have a topic with durable subscribers. 我有一个关于长期订阅者的话题。 I can publish and consume the messages, however I see there is some delay while reading the messages from topic. 我可以发布和使用消息,但是从主题中读取消息时会出现一些延迟。

I am not able read the messages in a single call. 我无法在单个通话中阅读消息。 I need to call the method multiple times to read the messages. 我需要多次调用该方法才能阅读消息。 Am I missing anything? 我有什么想念的吗?

    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;
}

You are calling receiveNoWait() which will retrieve one message at a time. 您正在调用receiveNoWait(),它将一次检索一条消息。 What normally happens, depending on your JMS provider, is that the JMS client will retrieve a number of messages at once and cache them on the client side to reduce network latency. 通常,根据您的JMS提供者的不同,JMS客户端将一次检索大量消息并将其缓存在客户端以减少网络延迟。 When you call receive it is then taking the message from this cache and giving it to you. 当您呼叫接收时,它将从此缓存中获取消息并将其提供给您。

If you are seeing minute long delays there is either something wrong with how you are putting these messages onto the topic or you are blocking your message receive while you process each message. 如果看到几分钟的延迟,则可能是您将这些消息放入主题的方式有问题,或者在处理每条消息时都阻止了消息的接收。 If you would like to not block your message receipt while processing take a look at implementing the MessageListener interface instead of the using the receive methods or you can take the messages from your receive method and process them on a thread pool asynchronously. 如果您不想在处理过程中阻塞消息接收,请考虑实现MessageListener接口而不是使用receive方法,或者您可以从receive方法获取消息并在线程池上异步处理它们。

When you create the consumer you can add the listener like so: 创建使用者时,可以像这样添加侦听器:

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

Then create a class to handle the messages or implement the interface in your existing consumer class: 然后创建一个类来处理消息或在现有的使用者类中实现接口:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM