当前位置: 首页 > 面试题库 >

处理Mongodb连接的正确方法是什么?

韩宜春
2023-03-14
问题内容

我使用10gen的本机node.js驱动器将mongodb(2.2.2)与node.js一起使用。

起初一切顺利。但是当涉及到并发基准测试部分时,会发生很多错误。频繁进行1000次并发连接/关闭可能会导致mongodb拒绝任何进一步的请求,并出现以下错误:

Error: failed to connect to [localhost:27017]

Error: Could not locate any valid servers in initial seed list

Error: no primary server found in set

另外,如果许多客户端在没有显式关闭的情况下关闭,则mongodb将花费几分钟的时间来检测并关闭它们。这也将导致类似的连接问题。(使用/var/log/mongodb/mongodb.log检查连接状态)

我已经尝试了很多。根据手册,mongodb没有连接限制,但是 poolSize 选项似乎对我没有影响。

因为我只在node-mongodb-native模块中使用过它,所以我不太确定最终导致问题的原因。其他语言和驱动程序的性能如何?

PS:当前,我想出了唯一的方法是使用自助池,但是使用它不能解决副本集的问题。根据我的测试,副本集似乎比独立的mongodb需要更少的连接。但是不知道为什么会这样。

并发测试代码:

var MongoClient = require('mongodb').MongoClient;

var uri = "mongodb://192.168.0.123:27017,192.168.0.124:27017/test";

for (var i = 0; i < 1000; i++) {
    MongoClient.connect(uri, {
        server: {
            socketOptions: {
                connectTimeoutMS: 3000
            }
        },
    }, function (err, db) {
        if (err) {
            console.log('error: ', err);
        } else {
            var col = db.collection('test');
            col.insert({abc:1}, function (err, result) {
                if (err) {
                    console.log('insert error: ', err);
                } else {
                    console.log('success: ', result);
                }
                db.close()
            })
        }
    })
}

通用池解决方案:

var MongoClient = require('mongodb').MongoClient;
var poolModule = require('generic-pool');

var uri = "mongodb://localhost/test";

var read_pool = poolModule.Pool({
    name     : 'redis_offer_payment_reader',
    create   : function(callback) {
        MongoClient.connect(uri, {}, function (err, db) {
            if (err) {
                callback(err);
            } else {
                callback(null, db);
            }
        });
    },
    destroy  : function(client) { client.close(); },
    max      : 400,
    // html" target="_blank">optional. if you set this, make sure to drain() (see step 3)
    min      : 200, 
    // specifies how long a resource can stay idle in pool before being removed
    idleTimeoutMillis : 30000,
    // if true, logs via console.log - can also be a function
    log : false 
});


var size = [];
for (var i = 0; i < 100000; i++) {
    size.push(i);
}

size.forEach(function () {
    read_pool.acquire(function (err, db) {
        if (err) {
            console.log('error: ', err);
        } else {
            var col = db.collection('test');
            col.insert({abc:1}, function (err, result) {
                if (err) {
                    console.log('insert error: ', err);
                } else {
                    //console.log('success: ', result);
                }
                read_pool.release(db);
            })
        }
    })
})

问题答案:

由于Node.js是单线程的,因此您不应该在每个请求上打开和关闭连接(就像在其他多线程环境中那样)。

这是写MongoDB node.js客户端模块的人的报价:

“当您的应用程序启动并重新使用db对象时,您只需打开一次MongoClient.connect。每个.connect都不是一个单例连接池。因此,请打开它并在所有请求中重用。”
-christkv https://groups.google.com/forum/#!msg/node-mongodb-
native/mSGnnuG8C1o/Hiaqvdu1bWoJ



 类似资料:
  • 我试试看。js与mongodb(2.2.2)一起使用本机节点。js drive by 10gen。 起初一切都很顺利。但在并发基准测试部分,出现了很多错误。频繁连接/关闭1000次并发可能会导致mongodb拒绝任何进一步的请求,错误如下: 此外,如果很多客户端在没有显式关闭的情况下关闭,mongodb需要几分钟来检测并关闭它们。这也会导致类似的连接问题。(使用/var/log/mongodb/m

  • 问题内容: 我正在使用Spring MVC在SQL Server数据库之上构建薄层。当我开始测试时,似乎不能很好地处理压力:)。我正在使用Apache Commons DBCP 来处理连接池和数据源。 当我第一次尝试同时建立约10-15个连接时,它曾经挂起,不得不重启服务器(对于开发人员,我正在使用Tomcat,但最终我将不得不在Weblogic上进行部署)。 这些是我的Spring bean定义

  • 问题内容: 我使用Node-Mongo-Native并尝试设置全局连接变量,但是我对两种可能的解决方案感到困惑。你们可以帮我选哪一个是好人吗?1.解决方案(这很糟糕,因为每个请求都将尝试创建新的连接。) 解决方案(在应用程序初始化时进行连接并将连接字符串分配给全局变量)。但我认为将连接字符串分配给全局变量不是一个好主意。 var mongodb; var url =’[connectionStri

  • 我使用Node Mongo Native并试图设置一个全局连接变量,但我对两种可能的解决方案感到困惑。你们能帮我找出哪一个是好的吗?1.解决方案(这很糟糕,因为每个请求都会尝试创建新连接。) 解决方案(在app init连接并将连接字符串分配给全局变量)。但我认为将连接字符串指定给全局变量不是一个好主意。 var mongodb;var url='[connectionString]';Mongo

  • 问题内容: 我遇到这种情况,我需要将a解析为an ,但我不知道该如何处理。当我没有抓住它时,编译器不会抱怨,但是我只是想确保自己能够正确处理这种情况。 我只想这样简化我的代码。编译器没有问题,但是线程在上死掉了。 Google CodePro希望我以某种方式记录该异常,并且我同意这是最佳实践。 我希望当当前片段不是数字或无法解析时返回此方法。当我没有显式捕获时,是否不分配变量?还是有一些默认值返回

  • 问题内容: 我一直在使用spring-webflux进行一些研究,我想了解使用路由器功能处理错误的正确方法。 我创建了一个小项目来测试几个场景,并且我希望获得有关它的反馈,并查看其他人在做什么。 到目前为止,我在做什么。 提供以下路由功能: 我已经在我的处理程序上执行了 它们是我的错误处理程序: 这是完整的示例存储库: https://github.com/LearningByExample/re