【发布时间】:2017-12-18 15:37:13
【问题描述】:
决定何时杀死听众的正确方法或流行惯例是什么?我似乎在任何地方都找不到可靠的答案。我正在处理的队列是 IBM 的 MQ 队列,我通常知道您会一直阅读,直到收到 2033 错误代码(我的公司在其他应用程序中这样做),此时您可以结束,但对于 SpringBoot Jms 应用程序这里有什么约定?一旦队列为空,侦听器就会挂起,直到有更多消息到来。如果我愿意,我知道如何杀死它,但我怎么知道何时?
作为一个例子,这是我放在一起的示例项目的配置
@Configuration
@EnableTransactionManagement
public class JmsConfig {
@Bean
protected DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory() throws JMSException {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(mqQueueConnectionFactory());
factory.setConcurrency("1");
factory.setSessionTransacted(true);
factory.setAutoStartup(true);
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
factory.setErrorHandler(new JmsErrorHandler());
return factory;
}
@Bean
public MQQueueConnectionFactory mqQueueConnectionFactory() {
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName(host);
try {
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setCCSID(1208);
mqQueueConnectionFactory.setChannel(channel);
mqQueueConnectionFactory.setPort(port);
mqQueueConnectionFactory.setQueueManager(queueManager);
} catch (Exception e) {
e.printStackTrace();
}
return mqQueueConnectionFactory;
}
这里是监听器
@Component
public class Consumer {
@JmsListener(id = "myQueue", destination = "queue")
public void processMessage(Message message) throws MQException, IOException {
try {
String messageString = ((TextMessage) message).getText();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
除了主类和ErrorHandler之外,它实际上就是整个示例项目,它会处理消息。我在其他应用程序中所做的是在给定队列值的情况下实例化 MQQueue,而 queue.getCurrentDepth() 很简单,如果我得到一个零,然后我调用一个 ListenerContainerController 的实例,然后在给定队列 ID 的情况下从 JmsListenerEndpointRegistry 调用 stop .
Spring 是否有一种简单的沟通方式“嘿,你的队列现在是空的”,或者有没有办法在 x 时间过去后结束它?
【问题讨论】:
-
为什么要关闭它?如果您让它继续运行,它将处理新消息(如果它们被放入该队列)。
-
@JoshMc 因为在这种情况下,我处理读取消息并根据我处理的内容生成报告,在该报告中应该清除队列并且什么都没有。这是一个日常运行的过程,我不确定我们是否希望它按照您的描述进行设置。您的评论让我想知道我是否在使用这个 JmsListener 有点不合常规。但无论是运行一次还是保持正确收听,该过程都必须在某个时候结束?
-
不要为此使用监听器。如果这就是您想要的全部内容,请使用
JmsTemplate并阅读直到没有更多内容可阅读。生成报告并完成它。侦听器旨在在消息出现时继续运行和处理消息。您甚至可以使用 Spring Batch 和JmsItemReader来阅读消息,直到没有更多内容可阅读。 -
@M.Deinum 哇。我学到了一些新东西,而且显然做错了。很长一段时间以来,我一直有一种代码味道,无法真正弄清楚为什么,我偶然发现的所有文档/资源以及我在这里遇到的问题的答案(也许我问了错误的问题......)让我相信JmsListener 是我在这种过程中所需要的。随意提取您对答案的评论并详细说明您认为合适的内容,我可以接受它,因为这将是我要走的路。已经阅读过文档。感谢您的评论。
-
使用此方法时,请务必使用
CachingConnectionFactory以便缓存消费者 - 这样可以避免模板必须为每条消息创建一个新消费者。
标签: java spring-boot ibm-mq spring-jms