我正在开发一个 Spring boot JMS 应用程序,该应用程序严格使用 bean 注释进行设置,并从 WebshpereMQ 读取消息。一切正常,除了我不知道如何安全地关闭这个应用程序。一旦我的 JMSListener 方法读取了所有消息,它就会保持空闲状态。我与队列建立初始连接并访问队列深度,因此理想情况下,当队列深度为零时,它需要将其包装并关闭。我当前的解决方法(我根本不喜欢它)是我调用的这个小方法(从侦听器内部,yikes) 当深度为零时:
public void shutDownApplication() {
logger.info("Initiating shutdown of application...");
System.out.println("Terminating application...");
Thread.currentThread().interrupt();
System.exit(0);
}
我不喜欢这个解决方案。 Spring 也没有,因为这显然是在进程中作为错误而中断的,在应用程序终止之前,我的 JMSListener 启动回滚并将最后一条剩余消息放回到队列中。
在查看以下来源后,我尝试了一些其他解决方案:
如何停止/启动/暂停@JmsListener(干净的方式) https://stackoverflow.com/questions/32588352/how-can-i-stop-start-pause-a-jmslistener-the-clean-way
如何优雅地关闭 Spring JMS MessageListenerAdapter https://stackoverflow.com/questions/1028025/how-to-gracefully-shut-down-a-spring-jms-messagelisteneradapter
http://forum.spring.io/forum/spring-projects/integration/jms/124980-graceful-shutdown-of-jms-message-listener http://forum.spring.io/forum/spring-projects/integration/jms/124980-graceful-shutdown-of-jms-message-listener
这是我最近的解决方案:
public class JMSShutdownService {
public void initiateShutdown() {
JmsListenerEndpointRegistry jmsListenerEndpointRegistry = new JmsListenerEndpointRegistry();
Collection<MessageListenerContainer> col = jmsListenerEndpointRegistry
.getListenerContainers();
for (MessageListenerContainer cont : col) {
cont.stop(Thread.currentThread());
}
System.exit(0);
}
}
这会终止应用程序,但仍将最后一条消息放回到队列中。我仍在尝试理解 Spring 的许多复杂之处,所以一切都归结为这一点。我觉得主要问题是它在我发出关闭信号的侦听器内部。据我所知,听众不应该为此负责。但我不确定如何定义一种在侦听器启动之前关闭应用程序的方法,或者如何在队列深度为零时从侦听器中弹出。
有任何想法吗?