6

I have the following log in my mongo console:

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)
....
....
....

likewise the log goes on and now it is in 112. Each time when i start mongo server this happens. I only have a singleton connection in my code. What can be the issue here:

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;
}
2
  • Are there multiple methods ? Can you make it synchronized ? Commented Jul 23, 2013 at 12:48
  • My DAOs will call this connector class method to get the connection. Also this connection is a static singleton one, so i expect it to have only one connection at a given time.... So, why do i need synchronized here??? Commented Jul 23, 2013 at 18:25

1 Answer 1

8

MongoClient has internal connection pool. Maximum number of connections can be configured (default is 100). You can set it by using MongoClientOptions like this:

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

And then give these options to MongoClient (checked it in Mongo Java API v2.11.1). Connections in pool are maintained open (opening and closing connection is usually an expensive operation) so that they can be later reused.

I would also refactor your MongoDB client singleton using enum for example to avoid putting synchronized on this method.

Here is a sketch of what I mean:

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();
    }
}

Then, you can access your database via

MongoDB.INSTANCE.getSomeDB().getCollection("someCollection").count();
Sign up to request clarification or add additional context in comments.

6 Comments

I expect only one active connection at a given time, thats why i have made it as a static singleton. How does configuring connection numbers will help here?
Also, can you please update with the refactoring you have mentioned?
How is your request originated? Is it submitted via browser? Please describe the flow in the question. Updated regarding singleton.
Understood. As far as I can tell Mongo starts with one open connection in the pool. So if this process does not run threads with access to MongoClient instance, then it should probably reuse the same connection. I would also check if some other process (besides your scheduled Akka job) opens connections. Try to limit number of connections to 2 for example, just to see if it is indeed only your process (you should not see more than 2 connections). Call close of MongoClient on process shutdown.
@AlexP Close method like 'MongoDBClass.INSTANCE.close()' during shutdown I dont understand. How can i call the method when i redeploying the project or restarting the tomcat server manually .Is there any code to predict the server stops and call the above close method .Or else there is no place to call the close method.Because when i call close method, after that the connection is not reopening until i shutdown the server and start it again.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.