【问题标题】:How to create multiple MQQueueConnectionFactory for multiple Queue Manager如何为多个队列管理器创建多个 MQQueueConnectionFactory
【发布时间】: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");
   }

【问题讨论】:

    标签: spring-boot jms ibm-mq message-queue spring-jms


    【解决方案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)。或者将那些@JmsListeners 放入同样在生产配置文件中的 bean 中(并调用其他 JmsListener 方法)。
    猜你喜欢
    • 2013-11-29
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 2021-05-14
    相关资源
    最近更新 更多