[英]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.