如何为多个队列管理器创建多个 MQQueueConnectionFactory
Posted
技术标签:
【中文标题】如何为多个队列管理器创建多个 MQQueueConnectionFactory【英文标题】:How to create multiple MQQueueConnectionFactory for multiple Queue Manager 【发布时间】:2020-11-03 05:39:02 【问题描述】:我正在尝试配置一个 @JMSListener,它将在我的 Springboot 应用程序中侦听多个队列管理器,该应用程序正在侦听 IBM MQ。下面是我创建的 2 个 bean,要求是主动监听两个队列:
@Value("$ibm.mq.queueManager.A")
String jmsMQConnectionFactoryA;
@Value("$ibm.mq.queueManager.B")
String jmsMQConnectionFactoryB;
@Bean
@Primary
public MQQueueConnectionFactory jmsMQConnectionFactoryB()
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
URL url = JMSConfiguration.getURL(this.urlFileLocation);
try
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT_Q_MGR);
mqQueueConnectionFactory.setCCDTURL(url);
mqQueueConnectionFactory.setQueueManager(jmsMQConnectionFactoryB);
catch (Exception e)
e.printStackTrace();
return mqQueueConnectionFactory;
@Bean
public MQQueueConnectionFactory jmsMQConnectionFactoryB()
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
URL url = JMSConfiguration.getURL(this.urlFileLocation);
try
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT_Q_MGR);
mqQueueConnectionFactory.setCCDTURL(url);
mqQueueConnectionFactory.setQueueManager(jmsMQConnectionFactoryA);
catch (Exception e)
e.printStackTrace();
return mqQueueConnectionFactory;
编辑 1:
使用上述连接和 2 个 JMSTemplate 添加了 2 个 containerFactory(因为我也需要发布消息)下面是更新的工作代码
@Bean
JmsListenerContainerFactory<?> jmsContainerFactoryA()
DefaultJmsListenerContainerFactory factory = new
DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(jmsMQConnectionFactoryA());
factory.setRecoveryInterval((long) 60000);
factory.setSessionAcknowledgeMode(2);
factory.setSessionTransacted(true);
// factory.setMaxMessagesPerTask(concurrencyLimit);
return factory;
@Bean
JmsListenerContainerFactory<?> jmsContainerFactoryB()
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(jmsMQConnectionFactoryB());
factory.setRecoveryInterval((long) 60000);
factory.setSessionAcknowledgeMode(2);
factory.setSessionTransacted(true);
// factory.setMaxMessagesPerTask(concurrencyLimit);
return factory;
@Bean
public MQQueue jmsResponseQueue()
MQQueue queue = null;
try
queue = new MQQueue("QueueOut");
queue.setBaseQueueName(wmq_out_base_queue);
catch (JMSException e)
e.printStackTrace();
return queue;
@Bean
public JmsTemplate jmsTemplateB()
JmsTemplate template = new JmsTemplate();
template.setConnectionFactory(jmsMQConnectionFactoryB());
template.setDefaultDestination(jmsResponseQueue());
template.setMessageConverter(oxmMessageConverter());
return template;
@Bean
public JmsTemplate jmsTemplateA()
JmsTemplate template = new JmsTemplate();
template.setConnectionFactory(jmsMQConnectionFactoryA());
template.setDefaultDestination(jmsResponseQueue());
template.setMessageConverter(oxmMessageConverter());
return template;
Class2.java
@Value("$wmq_out_base_queue")
String wmq_out_base_queue;
@Autowired
JmsTemplate jmsTemplateA;
@Autowired
JmsTemplate jmsTemplateB;
@JmsListener(containerFactory="jmsContainerFactoryA",destination = "$wmq_in_base_queue")
public void reciveMessageA(Message message)
LOGGER.info("Received message is: " + message);
this.jmsTemplateA.convertAndSend(wmq_out_base_queue, "Some Message");
@JmsListener(containerFactory="jmsContainerFactoryB",destination = "$wmq_in_base_queue")
public void reciveMessageB(Message message)
LOGGER.info("Received message is: " + message);
this.jmsTemplateA.convertAndSend(wmq_out_base_queue, "Some Message2");
【问题讨论】:
【参考方案1】:您需要禁用 JMS 自动配置并配置 2 个连接工厂、2 个使用这些连接工厂的容器工厂和 2 个 JmsTemplates(如果您还发布)。
我正在尝试配置一个 @JMSListener 来监听多个队列管理器
为了让@JmsListener
执行此操作,您需要向该方法添加2 个@JmsListener
注释,每个注释都将containerFactory
属性设置为各自的容器工厂。
【讨论】:
感谢您的建议。它现在正在工作。我还需要一个建议。要求是仅在生产中为另外 2 个队列管理器创建 2 个连接。因此,在生产环境中,我将拥有另外 2 个队列管理器 jmsMQConnectionFactoryC 和 jmsMQConnectionFactoryD 以及现有的,对于所有较低的环境,它将只有 jmsMQConnectionFactoryA 和 jmsMQConnectionFactoryA。设计这个的最佳方式是什么, 将 C & D 放在@Profile
中,以便它们仅在生产中注册 - 请参阅 docs.spring.io/spring/docs/5.2.7.RELEASE/…
感谢您的提示。现在在 spring.profiles.active & Profile 的帮助下,我能够控制 Bean 注册。但是我如何控制 JmsListener 方法呢?至于非 prod envs C & D bean 没有注册,我已经在 @JmsListener(containerFactory="jmsContainerFactoryC" 将抛出 bean not found 错误
而不是省略配置文件中的bean,用于容器工厂;将autoStartup
设置为false(使用@Value
并将属性设置为true 或false)。或者将那些@JmsListener
s 放入同样在生产配置文件中的 bean 中(并调用其他 JmsListener 方法)。以上是关于如何为多个队列管理器创建多个 MQQueueConnectionFactory的主要内容,如果未能解决你的问题,请参考以下文章