SpringJMS-如何断开MessageListenerContainer的连接

SpringJMS-如何断开MessageListenerContainer的连接,spring,jms,activemq,amqp,spring-jms,Spring,Jms,Activemq,Amqp,Spring Jms,我想断开队列的DefaultMessageListenerContainer。我正在使用dmlc.stop()、dmlc.shutdown()。在连接时,5个使用者线程连接到队列。当我尝试断开连接时,4个耗电元件断开连接,但1个耗电元件保持连接。(参见线程末尾的屏幕截图) 环境 1.带有AMQP的ActiveMQ 2.带ApacheQpid的SpringJMS 问题 调用destroy and stop方法后,仍然有一个使用者连接到队列 所需解决方案 我想知道,如何干净地断开消费者与队列零连接的

我想断开队列的DefaultMessageListenerContainer。我正在使用dmlc.stop()、dmlc.shutdown()。在连接时,5个使用者线程连接到队列。当我尝试断开连接时,4个耗电元件断开连接,但1个耗电元件保持连接。(参见线程末尾的屏幕截图)

环境 1.带有AMQP的ActiveMQ 2.带ApacheQpid的SpringJMS

问题 调用destroy and stop方法后,仍然有一个使用者连接到队列

所需解决方案

我想知道,如何干净地断开消费者与队列零连接的MessageListenerContainer

配置和代码

    @Bean
public DefaultMessageListenerContainer getMessageContainer(ConnectionFactory amqpConnectionFactory, QpidConsumer messageConsumer){
    DefaultMessageListenerContainer listenerContainer = new DefaultMessageListenerContainer();
    listenerContainer.setConcurrency("5-20");
    listenerContainer.setRecoveryInterval(jmsRecInterval);
    listenerContainer.setConnectionFactory(new CachingConnectionFactory(amqpConnectionFactory));
    listenerContainer.setMessageListener(messageConsumer);
    listenerContainer.setDestinationName(destinationName);
    return listenerContainer;
}

private void stopListenerIfRunning() {
        DefaultMessageListenerContainer dmlc = (DefaultMessageListenerContainer) ctx.getBean("messageContainer");
        if (null != dmlc) {
            if(!dmlc.isRunning()){return;}
            dmlc.stop(new Runnable() {
                @Override
                public void run() {
                    logger.debug("Closed Listener Container for Connection {}", sub.getQueueName());
                    if (sub.getSubscriptionStatus() == SubscriptionStatus.DELETED
                            || sub.getSubscriptionStatus() == SubscriptionStatus.SUSPENDED_DELETE) {
                        listenerHandles.remove(sub.getQueueName());
                    }
                }
            });
            dmlc.destroy();
            dmlc.shutdown();
        }

    }

}

listenerContainer.setConnectionFactory(newCachingConnectionFactory(amqpConnectionFactory))

您需要销毁
CachingConnectionFactory

您通常不需要侦听器容器的缓存工厂,因为会话是长期的;如果您具有可变并发性,则绝对不应该这样做;从javadocs

 * <p><b>Note: Don't use Spring's {@link org.springframework.jms.connection.CachingConnectionFactory}
 * in combination with dynamic scaling.</b> Ideally, don't use it with a message
 * listener container at all, since it is generally preferable to let the
 * listener container itself handle appropriate caching within its lifecycle.
 * Also, stopping and restarting a listener container will only work with an
 * independent, locally cached Connection - not with an externally cached one.
*注意:不要使用Spring的{@link org.springframework.jms.connection.CachingConnectionFactory}
*与动态缩放相结合。理想情况下,不要将其与消息一起使用
*侦听器容器,因为通常最好让
*侦听器容器本身在其生命周期内处理适当的缓存。
*此外,停止和重新启动侦听器容器只能在
*独立的本地缓存连接-不与外部缓存连接连接。

如果要缓存连接,请使用
SingleConnectionFactory
或在CCF上调用
setCacheConsumers(false)

我正在创建一个连接工厂,并在两个或多个侦听器中使用它。这是一个糟糕的方法吗?我应该为每个消息侦听器容器使用一个连接工厂吗?可以,但CCF默认缓存使用者。最好对侦听器容器使用
SingleConnectionFactory
。但是在这种情况下,您正在创建一个新的CCF
listenerContainer.setConnectionFactory(新的CachingConnectionFactory(amqpConnectionFactory))。这是错误的。