简体   繁体   English

嵌入式fladdoodle MongoDB进程不会停止

[英]Embeded flapdoodle MongoDB process won't stop

I am using an flapdoodle embedded MongoDB instance in my application.我在我的应用程序中使用了一个flapdoodle 嵌入式 MongoDB实例。

The embedded MongoDB starts up and works as expected, but the process of the embedded instance won't stop when the application is being stopped or the integration tests are over.嵌入式 MongoDB 启动并按预期工作,但是当应用程序停止或集成测试结束时,嵌入式实例的进程不会停止。

I am using the class below to manage the state of the embedded MongoDB instance.我正在使用下面的类来管理嵌入式 MongoDB 实例的状态。 Is there something missing to properly stop the embedded MongoDB?是否缺少正确停止嵌入式 MongoDB 的内容? Can we start the process of the embedded MongoDB instance as a daemon (so it won't keep the running, even when the application is being stoppped)?我们可以将嵌入式 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()));
    }
}

I had the same issue when using flapdoodle embedded MongoDB for development and while running the Spring application via gradle bootRun .在使用 fladdoodle 嵌入式 MongoDB 进行开发以及通过gradle bootRun运行 Spring 应用程序时,我遇到了同样的问题。 After stopping the process, the MongoDB server survived and with more and more runs instances piled up and also the data within the MongoDB stayed.停止该进程后,MongoDB 服务器存活了下来,并且越来越多的运行实例堆积起来,MongoDB 中的数据也保留了下来。

After quite some searching and trying out things I was able to solve the issue based on the answers provided in https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/issues/212经过一番搜索和尝试后,我能够根据https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/issues/212中提供的答案解决问题

My MongoDB Configuration Class looks quite similar and the key to the solution was to wait for MongodProcess mongod to properly stop through checking with mongod.isProcessRunning() .我的 MongoDB 配置类看起来非常相似,解决方案的关键是等待MongodProcess mongod通过检查mongod.isProcessRunning()正确停止。 The surrounding while loop is a bit hacky, but it works for me:周围的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);
            }
        }
    }
}

Maybe it can still help someone else who stumbles upon the same issue.也许它仍然可以帮助遇到同样问题的其他人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM