ActiveMQ队列的活动使用者过多

时间:2018-09-21 14:48:35

标签: java concurrency spring-integration activemq

我的Spring应用程序占用ActiveMQ队列。有两种方法。两种方法的ActiveMQ集成的初始部分都相同:

@Bean
public ConnectionFactory connectionFactory() {
    return new ActiveMQConnectionFactory();
}

@Bean
public Queue notificationQueue() {
    return resolveAvcQueueByJNDIName("java:comp/env/jms/name.not.important.queue");
}

单线程方法:

@Bean
public IntegrationFlow orderNotify() {
    return IntegrationFlows.from(Jms.inboundAdapter(connectionFactory()).destination(notificationQueue()),
            c -> c.poller(Pollers.fixedDelay(QUEUE_POLLING_INTERVAL_MS)
                                 .errorHandler(e -> logger.error("Can't handle incoming message", e))))
                           .handle(...).get();
}

但是我想使用几个工作线程使用消息,因此我将代码从入站适配器重构为消息驱动的通道适配器:

@Bean
public IntegrationFlow orderNotify() {
    return IntegrationFlows.from(Jms.messageDriverChannelAdapter(connectionFactory()).configureListenerContainer(c -> {
                final DefaultMessageListenerContainer container = c.get();
                container.setMaxConcurrentConsumers(notifyThreadPoolSize);
            }).destination(notificationQueue()))
                           .handle(...).get();
}

问题在于,当应用程序重新部署到Tomcat或为第二种方法重新启动时,它不会停止ActiveMQ的使用者。它在启动过程中会创建新的使用者。但是所有新消息都被路由到旧的“死”用户,因此它们位于“待处理消息”部分,而不会被出队。

这里可能是什么问题?

1 个答案:

答案 0 :(得分:2)

我相信,您必须完全停止Tomcat。通常,在重新部署应用程序期间,应该停止并正确清除Spring容器,但是看起来情况并非如此:Tomcat重新部署钩子缺少某些内容。因此,我建议将其完全停止。

另一个选择是忘记外部Tomcat,而只是迁移到具有启动嵌入式servlet容器功能的Spring Boot。这样,在重建和重新启动应用程序之后就不会有任何泄漏。