2011-12-20 4 views
2

영구 가입자가있는 주제가 있습니다. 메시지를 게시하고 소비 할 수 있지만 주제에서 메시지를 읽는 동안 약간의 지연이 있음을 알 수 있습니다.JMS에서 메시지를 소비하는 동안 지연 발생 주제

한 번의 통화로 메시지를 읽을 수 없습니다. 메시지를 읽으려면 메서드를 여러 번 호출해야합니다. 내가 놓친 게 있니?

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

답변

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()); 
    } 
} 
+0

예를, 구독자에 대해 사용 가능한 모든 메시지를 검색하려고합니다. 이것이 지정된 수의 메시지에 대한 루핑 이유입니다. 그것은 모든 메시지를 읽고 있지만 출판 직후는 아닙니다. 5-6 분 (때로는 그 이상)이 걸립니다. 디버 보 모드에서 내 jboss를 실행하면 메시지가 즉시 읽히는 중 단점이 있습니다. 그러나 정상 모드에서 실행하면 읽는 데 약간의 시간이 걸립니다. – John

+0

JBoss에 대해 언급 했으므로 JMS 공급자로 응용 프로그램 서버 내부에서 JBoss Messaging을 사용한다고 가정합니다. – gregwhitaker

+0

네 맞아. JBOSS에서 제공하는 JMS 서버를 사용하고 있습니다. 구성이 누락 되었습니까? – John

관련 문제