-274°C 2024-02-26 15:08 采纳率: 100%
浏览 34
已结题

Failed to stop bean 'org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_1

springboot 项目中重运行时出现:
Failed to stop bean 'org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_1
java.lang.IllegalStateException: Shutdown in progress
并且需要一段时间才会重启成功,这个问题咋解决啊。

  • 写回答

3条回答 默认 最新

  • 码农阿豪@新空间 新星创作者: 前端开发技术领域 2024-02-26 15:08
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如需一对一服务私聊我哦
    问题分析: 这个问题的出现通常是因为在关闭应用程序时,一些RocketMQ监听器仍然在活动状态,不允许此时关闭bean。所以我们需要解决一下两个问题:
    1. 如何确保在应用程序关闭之前,所有的RocketMQ监听器都已经停止了?
    2. 如果所有的RocketMQ监听器都已经停止,那么如何确保应用程序能够正确地启动? 解决方案:
    3. 确保所有的RocketMQ监听器都已经停止了 在springboot的应用程序中,我们通常会使用@PreDestroy注释来控制bean的销毁。我们可以利用这个特性来确保在应用关闭之前,所有的RocketMQ监听器都已经停止了。
    @Component
    public class RocketMQListenerContainerShutdownHook {
      @Autowired
      private List<DefaultRocketMQListenerContainer> listenerContainers;
      @PreDestroy
      public void destroy() {
        for (DefaultRocketMQListenerContainer container : listenerContainers) {
          container.destroy();
        }
      }
    }
    

    在上面的代码中,我们创建了一个用于停止RocketMQ监听器的RocketMQListenerContainerShutdownHook bean。这个bean将在应用程序关闭之前被调用。我们使用@Autowired注释注入了所有的DefaultRocketMQListenerContainer实例,并遍历它们,分别调用每个监听器的销毁方法。 2. 确保应用程序能够正确地启动 如果RocketMQ监听器正常停止,那么应用程序应该能够正常启动。但是,如果RocketMQ监听器没有正常停止,那么应用程序启动时可能会产生问题。这时,我们需要等待一段时间,直到RocketMQ监听器完全停止,然后再尝试启动应用程序。我们可以使用一个重试机制来实现这个目的。

    @Component
    public class ApplicationStartup implements ApplicationListener {
      private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationStartup.class);
      private static final int MAX_RETRIES = 5;
      @Autowired
      private DefaultRocketMQListenerContainer container;
      @Override public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
          int retries = 0;
          while (retries < MAX_RETRIES && !container.isActive()) {
            LOGGER.info("RocketMQ listener container is not active. Retrying in 5 seconds...");
            try {
              Thread.sleep(5000);
            } catch (InterruptedException e) {
              LOGGER.warn("Interrupted while waiting for RocketMQ listener container to stop.", e);
            }
            retries++;
          }
          if (container.isActive()) {
            LOGGER.info("RocketMQ listener container is active. Starting the application.");
            // start the application
          } else {
            LOGGER.error("Failed to start the application after {} retries.", MAX_RETRIES);
            // application startup failed
          }
        }
      }
    }
    

    在上面的代码中,我们创建了一个用于启动应用程序的ApplicationStartup bean。这个bean将在ApplicationContext初始化时被调用。我们使用@Autowired注释注入了DefaultRocketMQListenerContainer实例,并在应用程序启动之前检查它是否处于活动状态。如果它不处于活动状态,我们会将它设置为重试,最多重试5次。如果RocketMQ监听器在重试次数用完之前没有变为活动状态,那么应用程序启动将失败。 总结: 通过对应用程序的关闭和启动流程的控制,可以解决RocketMQ监听器在应用程序重启时出现的问题。通过使用注释控制bean的销毁并实现重试机制,可以确保应用程序完全停止并正确启动。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 3月5日
  • 已采纳回答 2月26日
  • 创建了问题 2月26日