2013-08-23 4 views
0

У меня проблема с контейнером JMS Listener. В случае, если я отключу контейнер слушателя, половина сообщений доставляется и обрабатывается слушателем. Вот моя конфигурация Spring:Spring JMS Listener Контейнер останавливает только половину слушателей

<bean id="ConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiName" value="JmsXA" /> 
</bean> 

<bean id="testQueue" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiName" value="queue/test" /> 
</bean> 

<bean id="listener" class="eu.cuptech.jms.listener.ExampleListener" /> 

<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    <property name="connectionFactory" ref="ConnectionFactory" /> 
    <property name="destination" ref="testQueue" /> 
    <property name="messageListener" ref="listener" /> 
    <property name="concurrency" value="1" /> 
</bean> 

ExampleListener здесь:

package eu.cuptech.jms.listener; 

import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.MessageListener; 
import javax.jms.TextMessage; 

public class ExampleListener implements MessageListener { 

    public void onMessage(Message message) { 
     try { 
      String msg = ((TextMessage) message).getText(); 
      System.out.println("MESSAGE TEXT: " + msg); 
     } catch (JMSException e) { 
      throw new RuntimeException(e); 
     } 
    } 

} 

Клиент Spring MVC контроллер со следующими методами:

send10Messages метод (обычный клиент JMS):

@Resource(name="ConnectionFactory") 
private ConnectionFactory connectionFactory; 

@Resource(name="testQueue") 
private Queue testQueue; 

@RequestMapping(value="send10", method = RequestMethod.GET) 
public String send10Messages(ModelMap model, HttpSession session) throws Exception { 
    sendTextMessages(10, "Test message: "); 
    return "redirect:/info"; 
} 

private void sendTextMessages(int count, final String prefix) throws Exception { 
    Connection connection = null; 
    Session session = null; 
    MessageProducer messageProducer = null; 
    try { 
     connection = connectionFactory.createConnection(); 

     session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 
     messageProducer = session.createProducer(testQueue); 
     connection.start(); 
     TextMessage message = session.createTextMessage(); 

     int i = 0; 
     while (i < count) { 
      message.setText(prefix + ++i); 
      messageProducer.send(message); 
      Thread.sleep(250); 
      System.out.println("Message " + prefix + i + " sent."); 
     } 

    } finally { 
     try { 
      if (messageProducer != null) 
       messageProducer.close(); 
      if (connection != null) 
       connection.close(); 
      if (session != null) 
       session.close(); 
     } catch (JMSException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

disableListener метод:

@Resource(name="listenerContainer") 
private DefaultMessageListenerContainer listenerContainer; 

@RequestMapping(value="disableListener", method = RequestMethod.GET) 
public String disableListener(ModelMap model, HttpSession session) { 
    listenerContainer.stop(new Runnable() { 
     public void run() { 
      System.out.println("JMS Listener stopped."); 
     } 
    }); 
    return "redirect:/info"; 
} 

enableListener метод

@Resource(name="listenerContainer") 
private DefaultMessageListenerContainer listenerContainer; 

@RequestMapping(value="enableListener", method = RequestMethod.GET) 
public String enableListener(ModelMap model, HttpSession session) { 
    listenerContainer.start(); 
    return "redirect:/info"; 
} 

При запуске сервера и отправлять сообщения, которые я получил этот журнал (это нормально):

INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 1 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 1 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 2 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 2 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 3 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 3 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 4 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 4 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 5 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 5 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 6 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 6 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 7 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 7 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 8 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 8 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 9 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 9 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 10 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 10 sent. 

Когда Я отключил контейнер слушателя и снова отправлял сообщения. Я получил это:

INFO [stdout] (listenerContainer-1) JMS Listener stopped. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 1 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 1 sent. 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 2 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 3 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 3 sent. 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 4 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 5 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 5 sent. 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 6 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 7 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 7 sent. 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 8 sent. 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 9 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 9 sent. 
INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 10 sent. 

Когда я включаю контейнер слушателя снова я получил это:

INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 2 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 4 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 6 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 8 
INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 10 

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

Я использую Spring 3.2.4.RELEASE (я тоже пытался 3.2.3.RELEASE), HornetQ 2.3.0.Final как удаленный JMS-сервер и JBoss 7.3.1.Final как сервер приложений.

ответ

2

Я предполагаю, что вы загружаете контейнер в контекст (контекст DispatcherServlet) и корневой контекст (контекст ContextLoaderListener). Это означает, что у вас есть 2 контейнера, и вы останавливаете их только в контексте сервлета.

Включить DEBUG протоколирование для org.springframework и изучить журналы инициализации боба.

Возможно, это должно быть только в корневом контексте.

+0

Вы совершенно правы. У меня был один и тот же файл конфигурации, используемый 'ContextLoaderListener' и' DispatcherServlet'. Я начал с [примера] Mkyong (http://www.mkyong.com/spring3/spring-3-mvc-hello-world-example/), который его настроил. Спасибо. –

+0

Вероятно, это также означает, что на фабрике соединений, которую вы получаете от JNDI, существует какое-то кэширование prefetch/consumer, что объясняет, почему 5 сообщений «застревают», ожидая, что этот конкретный контейнер начнет работу снова. –

Смежные вопросы