mongodb打开连接问题

pop*_*der 6 java mongodb

我的mongo控制台中有以下日志:

Tue Jul 23 17:20:01.301 [initandlisten] waiting for connections on port 27017
Tue Jul 23 17:20:01.401 [websvr] admin web console waiting for connections on port 28017
Tue Jul 23 17:20:01.569 [initandlisten] connection accepted from 127.0.0.1:58090 #1 (1 connection now open)
Tue Jul 23 17:20:01.570 [initandlisten] connection accepted from 127.0.0.1:58089 #2 (2 connections now open)
Tue Jul 23 17:20:21.799 [initandlisten] connection accepted from 127.0.0.1:58113 #3 (3 connections now open)
....
....
....
Run Code Online (Sandbox Code Playgroud)

同样,日志继续,现在它在112.每次当我启动mongo服务器时,这种情况发生.我的代码中只有一个单例连接.这可能是什么问题:

public static DB getConnection(String databaseName) throws AppConnectionException {

    if (null != db) {
        Logger.debug("Returning existing db connection...!");
        return db;
    }

    Logger.debug("Creating new db connection...!");
    final String connStr = PropertyRetreiver.getPropertyFromConfigurationFile("rawdata.url");

    try {

        final MongoClientURI uri = new MongoClientURI(connStr);
        final MongoClient client = new MongoClient(uri);
        db = client.getDB(databaseName);

    } catch (UnknownHostException e) {
        throw new AppConnectionException(
                "Unable to connect to the given host / port.");
    }

    return db;
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*x P 8

MongoClient有内部连接池.可以配置最大连接数(默认值为100).您可以使用以下方式设置它MongoClientOptions:

MongoClientOptions options = MongoClientOptions.builder()
                .connectionsPerHost(100)
                .autoConnectRetry(true)
                .build();
Run Code Online (Sandbox Code Playgroud)

然后将这些选项提供给MongoClient(在Mongo Java API v2.11.1中进行检查).池中的连接保持打开(打开和关闭连接通常是一项昂贵的操作),以便以后可以重用它们.

我还会使用enum例如重构您的MongoDB客户端单例来避免synchronized使用此方法.

这是我的意思草图:

public enum MongoDB {
    INSTANCE;

    private static final String MONGO_DB_HOST = "some.mongohost.com";
    private Mongo mongo;
    private DB someDB;

    MongoDB() {

        MongoClientOptions options = MongoClientOptions.builder()
                .connectionsPerHost(100)
                .autoConnectRetry(true)
                .readPreference(ReadPreference.secondaryPreferred())
                .build();

        try {
            mongo = new MongoClient(MONGO_DB_HOST, options);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        someDB = mongo.getDB("someDB");
         //authenticate if needed
         //boolean auth = someDB.authenticate("username", "password".toCharArray());
         //if(!auth){
         //     System.out.println("Error Connecting To DB");
         //}        
    }

    public DB getSomeDB() {
        return someDB;
    }

    //call it on your shutdown hook for example 
    public void close(){
        mongo.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过访问您的数据库

MongoDB.INSTANCE.getSomeDB().getCollection("someCollection").count();
Run Code Online (Sandbox Code Playgroud)

  • 了解.据我所知,Mongo从池中的一个开放连接开始.因此,如果此进程不运行具有访问MongoClient实例的线程,那么它应该重用相同的连接.我还会检查是否有其他进程(除了预定的Akka作业)打开连接.例如,尝试将连接数限制为2,只是为了查看它是否确实只是您的进程(您不应该看到超过2个连接).在进程关闭时调用MongoClient的"close". (2认同)