首页 > 解决方案 > 保存已经运行的侦听器容器并在新设置失败时回滚

问题描述

我有以下情况。我的应用程序从一个配置文件中读取,我在该文件中定义了队列、它的排他性、线程数和其他一些细节。当应用程序启动时,它会从该配置中读取并DirectMessageListenerContainer为每个声明的条目创建。我将这些容器保存在一个地图中,在其中我将每个容器与我给定的自定义名称相关联。

在启动时,如果发生任何故障,应用程序将无法运行,这正是我想要的。现在,关于问题。我创建了一种reload方法,允许用户更改配置而无需通过 JMX 重新启动应用程序。所以,当配置文件改变时,如果reload方法被调用,执行以下过程。检查新配置的有效性,如果正确,则用于设置新配置。为此,我首先停止所有容器,然后销毁它们。之后,我初始化新容器。就是这样。问题是,当停止、销毁或任何其他下一步发生异常时会发生什么。我处理异常,但问题是它会使当前设置损坏或半生不熟。我想要一个回滚功能,但我不确定如何做到这一点。因为在检查新配置的有效性后,我将其设置为当前配置。

我可以保存当前设置,检查新设置是否有效,如果没有,我可以再次初始化之前的设置。但是,在初始化前一个异常时,我可能会遇到另一个异常。

这是reload功能。RabbitManager是我创建的类,它没有什么特别之处,只是执行诸如stopdestroy等之类的操作。

public String reloadConfiguration() {
    Rules newRules;

    // checking validity of new rules, setting it, handling exceptions...

    try {
        // setting new rules
        // rules variable saves the current rules 
        rules = newRules;

        // basically calls stop in all the containers
        rabbitManager.stopAll();
        // basically calls destroy in all the containers
        rabbitManager.destroyAllContainers();
        rabbitManager
                .init(rules) // initializes an empty map and sets rules as new rule.
                .registerListeners(); // reads rules and creates DirectMessageListenerContainer for each setting
        log.info("Configuration has been successfully changed, and stopped");
        // returns are for jConsole/monitoring
        return "Configuration has been successfully changed, and stopped";
    } catch (Exception ex) {
        log.error("Exception occurred - "+ex.getMessage(), ex);
        // returns are for jConsole/monitoring
        return "Exception : "+ex.getMessage();
    }
}

我希望我的问题很清楚,如果需要任何东西或者您认为当前的方法有问题,或者我可能遗漏了一些观点,请告诉我。抱歉,标题含糊不清。

标签: javaspring-bootrabbitmqspring-amqp

解决方案


你为什么不只是stop()容器,只在新容器好时才销毁它们。如果新配置失败,则只有start()销毁新容器后的旧容器。


推荐阅读