0


I'm now using Netty as my backend webservice and MongoDB as my database.
At first, I'm very glad with the high performance of the combination of MongoDB and Netty.
But recently I checked the MongoDB logs(and db.serverStatus() command) and found a very very serious issue: Every time Netty handles a RESTful HttpRequest with messageReceived, one available connection of MongoDB is taken and never release even if I close the Netty Channel.
And since there're only 20,000 concurrent connections that MongoDB provide, every connection is very precious. If I can't solve this problem, my service will crash after receiving more than 20000 requests.
I also did an test case on singleton MongoDB, I found that under the situation without Netty, everything works fine (A Timer program keeping to query MongoDB). There's only one connection taken even if I execute more than 5 queries at a time.
How can I release the connection in MongoDB under Netty Framework? Seem like the problem come from Netty Framework. I've been seeking the solution to this issue for a long time.

I also added "connectTimeoutMS=10000&socketTimeoutMS=10000" to the MongoDB connection string, but seem useless. The connection will never end until I close the whole program.

Netty impl:

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
        throws Exception {
  HttpResponse httpResponse = null;
  HttpRequest request = (HttpRequest) e.getMessage();
  (... Query "Singleton([the way I implement][1])" MongoDB ...)
  httpResponse.setContent(responseBuffer);
  httpResponse.addHeader(HttpHeaders.Names.CONTENT_LENGTH,
  responseBuffer.readableBytes());
  ChannelFuture future = ctx.getChannel().write(httpResponse);
      future.addListener(ChannelFutureListener.CLOSE);
}

Singleton MongoDB impl:

public class MongoDbCore {

private static MongoDbCore mINSTANCE = null;

private static Logger logger = Logger
        .getLogger(MongoDbCore.class.getName());

private static DB db;
private static MongoClient mongoClient;

private MongoDbCore() {

}

public static MongoDbCore getInstance() {
    if (mINSTANCE == null) {
        mINSTANCE = new MongoDbCore();

        try {

            String connString = "mongodb://"
                    + Configs.MongoDB.DB_HOST
                    + ":"
                    + Configs.MongoDB.DB_PORT
                    + "/?connectTimeoutMS=10000&socketTimeoutMS=10000";

            mongoClient = new MongoClient(new MongoClientURI(connString));

            logger.info("ConnectionString=" + connString);

            db = mongoClient.getDB(Configs.MongoDB.MY_DB);

        } catch (UnknownHostException ex) {
            logger.info("Error while initialing the MongoDB.");
        }

    }
    return mINSTANCE;
}

public static DB getDb() {
    return db;
}

public boolean updateChannelStatusByChannelId(Integer tid, String status) {

    try {

        DBCollection coll = db.getCollection(Configs.MongoDB.DB.TABLE_REGS);

        BasicDBObject newDocument = new BasicDBObject();
        newDocument.append("$set",
                new BasicDBObject().append("status", status));

        BasicDBObject searchQuery = new BasicDBObject().append("tid", tid);

        coll.update(searchQuery, newDocument, false, false,
                WriteConcern.SAFE);

        return true;

    } catch (Exception ex) {

        return false;

    }

}

....

}


The way I query/update MongoDB:

MongoDbCore.getInstance().updateChannelStatusByChannelId(123, "abc");

Thanks!!

Cheng
  • 47
  • 2
  • 6
  • Is the Mongo(Client) object within your Netty application actually treated as a singleton? You should not create more than one of those. Also note that the Java driver will actually consume all connections it is allowed to. If your max connections setting in MongoOptions is set to something relatively low (10-100) you should be able to see if the amount of connections is capped to that number (and therefore you indeed only use one MongoClient instance) – Remon van Vliet Jun 07 '13 at 11:42
  • I've added the way I implement singleton MongoDB. I used to run MongoDB for maxConn=5 for experiment, and after opening more than 5 programs. It did crash. No newer connection is accepted. – Cheng Jun 07 '13 at 11:56
  • Thanks for your help!! I do an experiment: reconfigure --maxConn to 10 and simulate a HTTP post every 2 seconds. I found after 15 HTTP posts. Come to 14 success, 1 fail (all of the connections are forced to reset). Is that because the imcompatible of Netty? I'm somehow regret using MongoDB. – Cheng Jun 07 '13 at 15:20

1 Answers1

0

I later port my code to JSP/Servlet. Everything works fine. I'm almost 100% sure the problem comes from Netty and the incompatibility between Netty and MongoDB. No matter how many Posts I invoked, the connection count remain 1.

Cheng
  • 47
  • 2
  • 6