问题描述
我对JMS侦听器容器有奇怪的问题.如果禁用了侦听器容器,一半的消息将由侦听器传递和处理.这是我的Spring配置:
I have weired problem with a JMS Listener container. In case I disable the listener container, half of messages are delivered and processed by listener. Here is my Spring configuration:
<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控制器:
Client is Spring MVC Controller with following methods:
send10Messages 方法(普通的JMS客户端):
send10Messages method (common JMS client):
@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";
}
启动服务器并发送消息时,我收到了此日志(可以):
When I start server and send messages I got this log (It is OK):
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.
当我禁用侦听器容器并再次发送消息时,我得到了:
When I disable the listener container and send messages again I got this:
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.
当我再次启用侦听器容器时,我得到了:
When I enable the listener container again I got this:
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
问题在于,即使禁用了侦听器,侦听器也会处理每个奇怪的消息.我认为,启用侦听器容器后,所有消息都将由侦听器传递和处理,而禁用它时将不处理任何消息.
The problem is that every odd message is processed by listener even if listener is disabled. I expact that all messages will be delivered and processed by listener when I enable the listener container and no message will be processed when I disable it.
我使用的是Spring 3.2.4.RELEASE(我也尝试过3.2.3.RELEASE),HornetQ 2.3.0.Final作为远程JMS Server,JBoss 7.3.1.Final作为App服务器.
I'm using Spring 3.2.4.RELEASE (I was trying 3.2.3.RELEASE too), HornetQ 2.3.0.Final as remote JMS Server and JBoss 7.3.1.Final as App server.
推荐答案
我的猜测是,您正在将容器加载到Web上下文(DispatcherServlet
的上下文)和根上下文(ContextLoaderListener
的上下文)中).这意味着您有2个容器,并且只在servlet上下文中停止了一个.
My guess is that you are loading the container into both the web context (DispatcherServlet
's context) and the root context (ContextLoaderListener
's context). Which means you have 2 containers and you are only stopping the one in the servlet context.
打开DEBUG
日志记录org.springframework
,并检查Bean初始化日志.
Turn on DEBUG
logging for org.springframework
and examine the bean initialization logs.
它可能应该只在根上下文中.
It probably should be just in the root context.
这篇关于Spring JMS侦听器容器仅停止侦听器的一半的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!