Java 使用spring amqp ListenerContainer关闭应用程序会挂起或花费很长时间
我创建了一个简单的“Hello World”风格的应用程序来测试spring amqp和RabbitMQ。Spring上下文是使用Java 使用spring amqp ListenerContainer关闭应用程序会挂起或花费很长时间,java,spring,rabbitmq,spring-amqp,Java,Spring,Rabbitmq,Spring Amqp,我创建了一个简单的“Hello World”风格的应用程序来测试spring amqp和RabbitMQ。Spring上下文是使用ClassPathXmlApplicationContext从主函数加载的,它启动amqp并设置一个ListenerContainer,侦听队列上的消息并在指定的pojo上调用指定的方法。除了关闭应用程序外,一切正常。我在spring上下文中尝试了close()方法,该方法开始关闭ListenerContainer,关闭工作线程,但随后应用程序挂起,并且没有退出。我还
ClassPathXmlApplicationContext
从主函数加载的,它启动amqp并设置一个ListenerContainer,侦听队列上的消息并在指定的pojo上调用指定的方法。除了关闭应用程序外,一切正常。我在spring上下文中尝试了close()
方法,该方法开始关闭ListenerContainer,关闭工作线程,但随后应用程序挂起,并且没有退出。我还尝试了上下文上的stop()
,以及ListenerContainer bean上的shutdown()
问题:
如何干净地关闭具有spring amqp ListenerContainers的spring上下文
以下是关机期间的日志输出:
Jul 07, 2014 1:00:22 AM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@472a2a50: startup date [Mon Jul 07 01:00:08 CEST 2014]; root of context hierarchy
Jul 07, 2014 1:00:22 AM org.springframework.context.support.DefaultLifecycleProcessor stop
INFO: Stopping beans in phase 2147483647
Jul 07, 2014 1:00:22 AM org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer doShutdown
INFO: Waiting for workers to finish.
Jul 07, 2014 1:00:23 AM org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer doShutdown
INFO: Successfully waited for workers to finish.
此输出后,应用程序挂起且不退出
以下是主要方法:
public static void main(String[] args) {
final ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:app-config.xml");
ctx.registerShutdownHook();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Quitting from Main...");
ctx.close();
}
}, 10000);
}
下面是app-config.xml
<beans ...>
<context:annotation-config />
<import resource="amqp-config.xml" />
<bean id="messageReceiver" class="com.knesek.amqp.spring.MessageReceiver" />
</beans>
以及spring amqp相关配置(amqp config.xml):
听起来您有一些非守护进程线程使您的上下文保持活动状态。关闭上下文将停止任何框架线程。我建议您使用jstack/visualvm进行线程转储。在调查线程转储后,似乎计时器
等待安排新任务会阻止关闭。在ctx.close()之前添加timer.cancel()
解决了问题。你的回答让我找到了解决办法,所以我接受了。
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns="http://www.springframework.org/schema/rabbit" ...>
<connection-factory id="connectionFactory" username="guest" password="guest" host="127.0.0.1"/>
<template id="amqpTemplate" connection-factory="connectionFactory"/>
<admin connection-factory="connectionFactory" />
<direct-exchange name="incomingMessages">
<bindings>
<binding key="messages.inbound" queue="inboundMsgs"/>
</bindings>
</direct-exchange>
<listener-container id="listenerContainer" connection-factory="connectionFactory" >
<listener ref="messageReceiver" method="receiveMessage" queues="inboundMsgs" />
</listener-container>
<queue name="inboundMsgs"/>
</beans:beans>