簡體   English   中英

無法在 Spring 引導中停止 IBM MQ JMS 使用者

[英]Not able to stop an IBM MQ JMS consumer in Spring Boot

我無法使用Spring Boot REST 端點動態停止JMS使用者。 消費者數量保持不變。 也沒有例外。

IBM MQ Version: 9.2.0.5

pom.xml

<dependency>
    <groupId>com.ibm.mq</groupId>
    <artifactId>mq-jms-spring-boot-starter</artifactId>
    <version>2.0.8</version>
</dependency>

JmsConfig.java

@Configuration
@EnableJms
@Log4j2
public class JmsConfig {
    @Bean
    public MQQueueConnectionFactory mqQueueConnectionFactory() {
        MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
        mqQueueConnectionFactory.setHostName("my-ibm-mq-host.com");
        try {
            mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
            mqQueueConnectionFactory.setCCSID(1208);
            mqQueueConnectionFactory.setChannel("my-channel");
            mqQueueConnectionFactory.setPort(1234);
            mqQueueConnectionFactory.setQueueManager("my-QM");
        } catch (Exception e) {
            log.error("Exception while creating JMS connecion...", e.getMessage());
        }
        return mqQueueConnectionFactory;
    }
}

JmsListenerConfig.java

@Configuration
@Log4j2
public class JmsListenerConfig implements JmsListenerConfigurer {
    @Autowired
    private JmsConfig jmsConfig;
    private Map<String, String> queueMap = new HashMap<>();

    @Bean
    public DefaultJmsListenerContainerFactory mqJmsListenerContainerFactory() throws JMSException {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(jmsConfig.mqQueueConnectionFactory());
        factory.setDestinationResolver(new DynamicDestinationResolver());
        factory.setSessionTransacted(true);
        factory.setConcurrency("5");
        return factory;
    }

    @Override
    public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
        queueMap.put("my-queue-101", "101");
        log.info("queueMap: " + queueMap);

        queueMap.entrySet().forEach(e -> {
            SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
            endpoint.setDestination(e.getKey());
            endpoint.setId(e.getValue());
            try {
                log.info("Reading message....");
                endpoint.setMessageListener(message -> {
                    try {
                        log.info("Receieved ID: {} Destination {}", message.getJMSMessageID(), message.getJMSDestination());
                    } catch (JMSException ex) {
                        log.error("Exception while reading message - " + ex.getMessage());
                    }
                });
                registrar.setContainerFactory(mqJmsListenerContainerFactory());
            } catch (JMSException ex) {
                log.error("Exception while reading message - " + ex.getMessage());
            }
            registrar.registerEndpoint(endpoint);
        });
    }
}

JmsController.java

@RestController
@RequestMapping("/jms")
@Log4j2
public class JmsController {
    @Autowired
    ApplicationContext context;

    @RequestMapping(value = "/stop", method = RequestMethod.GET)
    public @ResponseBody
    String haltJmsListener() {
        JmsListenerEndpointRegistry listenerEndpointRegistry = context.getBean(JmsListenerEndpointRegistry.class);

        Set<String> containerIds =  listenerEndpointRegistry.getListenerContainerIds();
        log.info("containerIds: " + containerIds);

        //stops all consumers
        listenerEndpointRegistry.stop(); //DOESN'T WORK :(

        //stops a consumer by id, used when there are multiple consumers and want to stop them individually
        //listenerEndpointRegistry.getListenerContainer("101").stop(); //DOESN'T WORK EITHER :(

        return "Jms Listener stopped";
    }
}

這是我注意到的結果。

  1. 初始消費者數量:0(如預期)
  2. 服務器啟動和隊列連接后,消費者總數:1(如預期)
  3. 在點擊http://localhost:8080/jms/stop端點后,消費者總數:1(不符合預期,應該 go 回到 0)

我是否缺少任何配置?

您還需要在容器上調用shutDown 請參閱我對此答案的評論DefaultMessageListenerContainer 的“isActive”與“isRunning”

start()/stop()設置/重置running initialize()/shutDown()設置/重置active 這取決於你的要求是什么。 stop()只是阻止消費者獲取新消息,但消費者仍然存在。 shutDown()關閉消費者。 大多數人調用stop + shutdown然后initialize + start重新啟動。 但是,如果您只想在短時間內停止消費,您只需要停止/開始即可。

您將需要遍歷容器並將它們強制轉換為調用shutDown()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM