0


我现在使用 Netty 作为我的后端 Web 服务,使用 MongoDB 作为我的数据库。
一开始,我很高兴MongoDB和Netty结合的高性能。
但最近我检查了 MongoDB 日志(和 db.serverStatus() 命令),发现了一个非常非常严重的问题:每次 Netty 处理带有 messageReceived 的 RESTful HttpRequest 时,都会占用一个可用的 MongoDB 连接并且即使我关闭 Netty 也不会释放渠道。
而且由于 MongoDB 提供的并发连接只有 20,000 个,所以每个连接都非常宝贵。如果我不能解决这个问题,我的服务会在收到超过 20000 个请求后崩溃。
我还在单例 MongoDB 上做了一个测试用例,我发现在没有 Netty 的情况下,一切正常(一个不断查询 MongoDB 的 Timer 程序)。即使我一次执行超过 5 个查询,也只会建立一个连接。
Netty框架下如何释放MongoDB中的连接?似乎问题来自Netty Framework。我一直在寻找这个问题的解决方案。

我还在 MongoDB 连接字符串中添加了“connectTimeoutMS=10000&socketTimeoutMS=10000”,但似乎没用。在我关闭整个程序之前,连接永远不会结束。

网络实现:

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

单例 MongoDB 实现:

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;

    }

}

....

}


我查询/更新 MongoDB 的方式:

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

谢谢!!

4

1 回答 1

0

我稍后将我的代码移植到 JSP/Servlet。一切正常。我几乎 100% 确定问题来自 Netty 以及 Netty 和 MongoDB 之间的不兼容。无论我调用了多少个帖子,连接数都保持为 1。

于 2013-06-08T04:53:34.733 回答