gpt4 book ai didi

node.js - 处理Mongodb连接的正确方法是什么?

转载 作者:IT老高 更新时间:2023-10-28 13:05:04 33 4
gpt4 key购买 nike

我使用 10gen 的 native node.js 驱动器一起尝试 node.js 和 mongodb (2.2.2)。

起初一切都很顺利。但是当来到并发基准测试部分时,出现了很多错误。频繁连接/关闭 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,
// 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 客户端模块的人的引述:

“You open do MongoClient.connect once when your app boots up and reuse the db object. It's not a singleton connection pool each .connect creates a new connection pool. So open it once an[d] reuse across all requests.” - christkv https://groups.google.com/forum/#!msg/node-mongodb-native/mSGnnuG8C1o/Hiaqvdu1bWoJ

关于node.js - 处理Mongodb连接的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15680985/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com