簡體   English   中英

嵌入式fladdoodle MongoDB進程不會停止

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM