SpringJMS - How to Disconnect a MessageListenerContainer

可紊 提交于 2021-01-28 08:27:58

问题


I want to disconnect the DefaultMessageListenerContainer for a queue. I am using dmlc.stop(), dmlc.shutdown(). At the time of conneciton 5 consumer threads get connected to queue. when I try to disconnect, 4 of the consumers get disconnected, but 1 consumer remains connected. (See screenshot at the end of thread).

Environment 1. ActiveMQ with AMQP 2. SpringJMS with ApacheQpid

Problem After calling destroy and stop method, there's still one consumer connected to the queue.

Required Solution

I want to know, how to cleanly disconnect a MessageListenerContainer with zero consumer connections to the queue.

Configurations and Code

    @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();
        }

    }

}


回答1:


listenerContainer.setConnectionFactory(newCachingConnectionFactory(amqpConnectionFactory));

You need to destroy the CachingConnectionFactory.

You generally don't need a caching factory with the listener container since the sessions are long-lived; you definitely should not if you have variable concurrency; from the 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.

if you want the connection cached, use a SingleConnectionFactory or call setCacheConsumers(false) on the CCF.



来源:https://stackoverflow.com/questions/48302077/springjms-how-to-disconnect-a-messagelistenercontainer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!