【问题标题】:Netty HTTP + MongoDB: Unlimited Increment in connectionsNetty HTTP + MongoDB:连接无限增量
【发布时间】:2013-06-07 11:35:23
【问题描述】:


我现在使用 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”,但似乎没用。在我关闭整个程序之前,连接永远不会结束。

Netty 实现:

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

谢谢!!

【问题讨论】:

  • 您的 Netty 应用程序中的 Mongo(Client) 对象实际上是否被视为单例?您不应创建多个其中之一。另请注意,Java 驱动程序实际上将使用它允许的所有连接。如果您在 MongoOptions 中的最大连接数设置设置为相对较低的值(10-100),您应该能够查看连接数是否限制为该数字(因此您确实只使用了一个 MongoClient 实例)
  • 我添加了实现单例 MongoDB 的方式。我曾经运行 MongoDB for maxConn=5 进行实验,并在打开超过 5 个程序后。它确实崩溃了。不接受较新的连接。
  • 感谢您的帮助!!我做了一个实验:将 --maxConn 重新配置为 10 并每 2 秒模拟一次 HTTP 帖子。我在 15 个 HTTP 帖子后发现。 14 次成功,1 次失败(所有连接都被强制重置)。是因为Netty不兼容吗?我有点后悔使用 MongoDB。

标签: mongodb rest netty nio mongodb-java


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多