【问题标题】:SpringJMS - How to shutdown a DefaultMessageListenerContainer gracefully so that all consumers are stopped/killedSpringJMS - 如何优雅地关闭 DefaultMessageListenerContainer 以便所有消费者都停止/杀死
【发布时间】:2021-03-19 07:42:27
【问题描述】:

DefaultMessageListenerContainer.shutdown 或 DefaultMessageListenerContainer.destroy 不会从队列中删除使用者。

这是一个类似的帖子:SpringJMS - How to Disconnect a MessageListenerContainer

(不知道怎么解决)

下面是我的代码:

public class MainProgram {
 private static final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MessageConsumerFacade.class); 
 public static final DefaultMessageListenerContainer container = context.getBean(DefaultMessageListenerContainer.class); 


public static void main(String[] args) throws InterruptedException {
   boolean startListener = isStartListener();   // to start and stop listener at 
    will
   if(startListener){
     if (!container.isRunning()) {
       container.start(); 
     }
   }else{
      if (container.isRunning()) {
         container.stop();
   }
 }
}
}


public class MessageConsumerFacade {
private ConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL(url);
        connectionFactory.setUserName(userName);
        connectionFactory.setPassword(password);

        RedeliveryPolicy policy = connectionFactory.getRedeliveryPolicy();
        policy.setInitialRedeliveryDelay(30000);
        policy.setRedeliveryDelay(30000);
        policy.setMaximumRedeliveries(2);
        connectionFactory.setNonBlockingRedelivery(true);
        return connectionFactory;
    }

    @Bean
    public MessageListenerContainer listenerContainer() {
        DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
        container.setConnectionFactory(connectionFactory());
        container.setDestinationName(queueName);
        container.setMessageListener(new MessageJmsListener());
        container.setCacheLevel(DefaultMessageListenerContainer.CACHE_NONE);
        container.setErrorHandler(new MessageErrorHandler());
        container.setSessionTransacted(true);
        container.setAutoStartup(false);
        container.shutdown();
        return container;
    }
}


public class MessageJmsListener implements MessageListener {
    
  @Override
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                //process the message and create record in Data Base                
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }     
}


public class MessageErrorHandler implements ErrorHandler {  
    
    @Override
    public void handleError(Throwable t) {
        //log error      
    }
}```

【问题讨论】:

    标签: activemq spring-jms shutdown consumer message-listener


    【解决方案1】:

    stop() 之后调用shutDdwn()

    How to pause/resume individual Spring JMS message listeners

    (顺便说一句,您在 bean 定义中对 shutdown() 的调用不会做任何事情,因为它还没有开始)。

    【讨论】:

    • 嗨,加里,谢谢您的回复。我看了你提到的另一个帖子。在我的情况下,我只有一个容器,并且在我的程序第一次运行时,它会创建一个新的消费者,正如我从 Active MQ 控制台中看到的那样。我面临的挑战是....对于签入/部署的每个新代码,上面的主程序正在启动另一个新的消费者....我想杀死旧的消费者并在每次我的主程序重新启动/刷新其上下文时启动 frsh .我怎样才能做到这一点。我尝试在停止后调用关机并在开始前初始化......但它没有帮助..我只想要1个干净的消费者。
    • >for every new code checked in/ deployed the Main program above is starting another new consumer 我不明白 - 当您重新部署时,您通常会取消部署旧实例,这会杀死消费者。您应该在关闭期间关闭应用程序上下文。
    • 嗨,Gary,我对 spring 很陌生...您能看看上面的主程序,并告诉我如何/在哪里正确关闭应用程序上下文...这样每当我们部署一些新代码时它关闭/杀死以前的消费者并干净地启动另一个新消费者
    • 很难说;您的 MainProgram 不是有效的 Java。将应用程序上下文存储在静态字段中是相当不寻常的。我建议你搜索一些 Spring 教程。考虑使用Spring Boot 以获得更轻松的入门体验。在您对 Spring 有一些基本了解之前,Stack Overflow 不是合适的地方。
    • 嗨,加里,我完全删除了 AnnotationConfigApplicationContext,而是在不使用 AnnotationConfigApplicationContext 的情况下初始化 DefaultMessageListenerContainer。问题依然存在。所以问题不在于 Spring AnnotationConfigApplicationContext 而是 DefaultMessageListenerContainer 实例被杀死的方式。停止和关闭没有帮助。我最终还是被老消费者吊死了……而且它永远不会被杀死。它是否以某种方式缓存,这个stackoverflow.com/questions/48302077/… 谈论相同。
    猜你喜欢
    • 2013-01-21
    • 2019-03-10
    • 2020-08-11
    • 2019-09-23
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多