[英]Embeded flapdoodle MongoDB process won't stop
我在我的应用程序中使用了一个flapdoodle 嵌入式 MongoDB实例。
嵌入式 MongoDB 启动并按预期工作,但是当应用程序停止或集成测试结束时,嵌入式实例的进程不会停止。
我正在使用下面的类来管理嵌入式 MongoDB 实例的状态。 是否缺少正确停止嵌入式 MongoDB 的内容? 我们可以将嵌入式 MongoDB 实例的进程作为守护进程启动(因此即使应用程序停止,它也不会继续运行)?
package ch.somePackage.configuration;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.Objects;
@Configuration
public class DbConfiguration {
final static Logger logger = LoggerFactory.getLogger(DbConfiguration.class);
private static final ConnectionString CONNECTION_STRING = new ConnectionString("mongodb://localhost:12345/some-db");
@Bean
public MongoHolder mongoHolder() {
return new MongoHolder();
}
public static class MongoHolder {
private MongoClient mongoClient;
private MongodExecutable mongodExecutable;
private MongodProcess mongod;
@PostConstruct
public void init() throws IOException {
final MongodStarter starter = MongodStarter.getDefaultInstance();
final String bindIp = "localhost";
final int port = 12345;
final IMongodConfig mongodConfig = new MongodConfigBuilder()
.version(Version.Main.PRODUCTION)
.net(new Net(bindIp, port, Network.localhostIsIPv6()))
.build();
try {
mongodExecutable = starter.prepare(mongodConfig);
mongod = mongodExecutable.start();
mongoClient = new MongoClient(bindIp, port);
logger.info("Started embedded mongo.");
} catch (final Exception e) {
e.printStackTrace();
}
}
@PreDestroy
public final synchronized void destroy() {
if (mongodExecutable != null) {
logger.info("Stopping embedded mongo.");
mongoClient.close();
mongodExecutable.stop();
mongod.stop();
logger.info("Stopped embedded mongo.");
}
}
public MongoClient getMongoClient() {
return mongoClient;
}
}
@Bean
public MongoDatabase mongoDatabase(final MongoHolder mongoHolder) {
return mongoHolder.getMongoClient().getDatabase(Objects.requireNonNull(CONNECTION_STRING.getDatabase()));
}
}
在使用 fladdoodle 嵌入式 MongoDB 进行开发以及通过gradle bootRun
运行 Spring 应用程序时,我遇到了同样的问题。 停止该进程后,MongoDB 服务器存活了下来,并且越来越多的运行实例堆积起来,MongoDB 中的数据也保留了下来。
经过一番搜索和尝试后,我能够根据https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/issues/212中提供的答案解决问题
我的 MongoDB 配置类看起来非常相似,解决方案的关键是等待MongodProcess mongod
通过检查mongod.isProcessRunning()
正确停止。 周围的while
循环有点hacky,但它对我有用:
@Configuration
@Profile("dev")
public class EmbeddedMongoConfig {
Logger logger = LoggerFactory.getLogger(EmbeddedMongoConfig.class);
private static final String CONNECTION_STRING = "mongodb://%s:%d";
private static final String HOST = "localhost";
private static final int PORT = 27017;
private MongodExecutable mongodExecutable;
private MongodProcess mongod;
private MongoClient client;
@Bean
public MongoTemplate mongoTemplate() throws Exception {
ImmutableMongodConfig mongoDbConfig = MongodConfig.builder()
.version(Version.Main.PRODUCTION)
.net(new Net(HOST, PORT, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongoDbConfig);
mongod = mongodExecutable.start();
client = MongoClients.create(String.format(CONNECTION_STRING, HOST, PORT));
return new MongoTemplate( client, "sampledatabase");
}
/*
* solution found here: https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/issues/212
*/
@PreDestroy
public void shutdownGracefully() {
if (client != null)
client.close();
if (mongod != null)
try {
mongod.stop();
} catch (IllegalStateException e) {
logger.error("Can't stop mongod", e);
}
if (mongod != null) {
int limit = 5;
int counter = 0;
while (mongod.isProcessRunning() && counter < limit) {
try {
counter++;
Thread.sleep(2000);
} catch (InterruptedException e) {
break;
}
}
}
if (mongodExecutable != null) {
try {
mongodExecutable.stop();
} catch (IllegalStateException e) {
logger.error("Can't stop mongodExecutable", e);
}
}
}
}
也许它仍然可以帮助遇到同样问题的其他人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.