动态重新加载Spring Mongo数据库连接而无需重新启动服务器

时间:2022-09-11 16:31:05

We're deploying a spring-based webapp in Tomcat and we'd like to give the user an option of which mongo database to connect to. To do this, we have a set-up wizard that captures the mongo connection details from the user through an online form. After capturing these details, we'd like to dynamically connect to Mongo. Right now we load our mongo via xml configuration:

我们在Tomcat中部署了一个基于spring的webapp,我们想让用户选择连接哪个mongo数据库。为此,我们有一个设置向导,通过在线表单从用户捕获mongo连接详细信息。捕获这些细节后,我们想动态连接到Mongo。现在我们通过xml配置加载我们的mongo:

<bean id="configmapper" class="com.db.util.ConfigurationMapper" />
<bean id="configmap" factory-bean="configmapper" factory-method="readXML" />
<mongo:mongo host="#{configmap.getHost()}" port="#{configmap.getPort()}" />
<mongo:db-factory dbname="#{configmap.getName()}"
    mongo-ref="mongo" />

The user values are stored read/written by the config mapper bean, but after setting them, we want to basically "restart" the mongo driver. To do this we are trying:

用户值由config mapper bean存储读/写,但在设置之后,我们希望基本上“重启”mongo驱动程序。要做到这一点,我们正在尝试:

XmlWebApplicationContext context = ((XmlWebApplicationContext) ContextLoader
            .getCurrentWebApplicationContext());
context.refresh();

This has the nice result of reloading all of our applciation beans, and we can even see the Mongo beans re-created in the log along with all the other beans in the context:

这具有重新加载所有applciation bean的好结果,我们甚至可以看到在日志中重新创建Mongo bean以及上下文中的所有其他bean:

DEBUG 2015-05-12 21:09:29,590 [http-nio-8087-exec-6] (DefaultSingletonBeanRegistry.java:221) - Creating shared instance of singleton bean 'mongo'
...
DEBUG 2015-05-12 21:09:08,121 [localhost-startStop-1] (DefaultSingletonBeanRegistry.java:221) - Creating shared instance of singleton bean 'mongoTemplate'
...
DEBUG 2015-05-12 21:09:29,590 [http-nio-8087-exec-6] (AbstractAutowireCapableBeanFactory.java:449) - Creating instance of bean 'mongoDbFactory'

However, when we go to use the connection, we get the following stacktrace:

但是,当我们使用连接时,我们得到以下stacktrace:

Caused by: java.lang.IllegalStateException: open
    at org.bson.util.Assertions.isTrue(Assertions.java:36)
    at com.mongodb.DBTCPConnector.isMongosConnection(DBTCPConnector.java:367)
    at com.mongodb.Mongo.isMongosConnection(Mongo.java:622)
    at com.mongodb.DBCollection.findOne(DBCollection.java:936)
    at com.mongodb.DBCollection.findOne(DBCollection.java:914)
    at com.mongodb.DBCollection.findOne(DBCollection.java:858)
    at org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java:2069)
    at org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java:2053)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:1828)
    at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:1645)
    at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:560)

We thought perhaps the mongo connection wasn't properly being closed so we brought in our mongo bean and closed it before reloading:

我们想也许mongo连接没有正确关闭所以我们引入了我们的mongo bean并在重新加载之前将其关闭:

@Autowired
private Mongo mongo;
...
mongo.close();
XmlWebApplicationContext context = ((XmlWebApplicationContext) ContextLoader
                .getCurrentWebApplicationContext());
context.refresh();

But we receive the same exception.

但我们收到同样的例外。

Does anyone know how we can go about achieving dynamic mongo reconnection without restarting our app server? Perhaps there is another way to go about this problem? We'd like to provide the end-user with a GUI web config as opposed to having to edit the config file themselves.

有没有人知道如何在不重新启动我们的应用服务器的情况下实现动态mongo重新连接?也许还有另一种方法可以解决这个问题?我们希望为最终用户提供GUI Web配置,而不是自己编辑配置文件。

Thanks for any advice you can provide.

感谢您提供的任何建议。

1 个解决方案

#1


I had a similar issue when accessing the database from the spring application context. After days worth of investigation i finally figured out that there was a timing issue and introducing a delay after setting the database credentials and before reload the context again solved the issue. For some reason my reloading of the context was being done too early and the database settings were not yet set at the time it tried to reload.

从spring应用程序上下文访问数据库时遇到了类似的问题。经过几天的调查后,我终于发现存在时间问题,并在设置数据库凭据之后引入延迟,并在重新加载上下文之前再次解决了问题。出于某种原因,我重新加载上下文的时间过早,并且在尝试重新加载时尚未设置数据库设置。

Once the delay was introduced, everything started working as expected.

一旦引入延迟,一切都按预期开始工作。

I hope it helps.

我希望它有所帮助。

#1


I had a similar issue when accessing the database from the spring application context. After days worth of investigation i finally figured out that there was a timing issue and introducing a delay after setting the database credentials and before reload the context again solved the issue. For some reason my reloading of the context was being done too early and the database settings were not yet set at the time it tried to reload.

从spring应用程序上下文访问数据库时遇到了类似的问题。经过几天的调查后,我终于发现存在时间问题,并在设置数据库凭据之后引入延迟,并在重新加载上下文之前再次解决了问题。出于某种原因,我重新加载上下文的时间过早,并且在尝试重新加载时尚未设置数据库设置。

Once the delay was introduced, everything started working as expected.

一旦引入延迟,一切都按预期开始工作。

I hope it helps.

我希望它有所帮助。