Node.js Mongodb服务器套接字在replSet上关闭
当我们并行进行大量连接时,mongodb套接字会关闭 下面是一个测试脚本:Node.js Mongodb服务器套接字在replSet上关闭,node.js,mongodb,sockets,Node.js,Mongodb,Sockets,当我们并行进行大量连接时,mongodb套接字会关闭 下面是一个测试脚本: var mongodb = require("mongodb"); var async = require("async"); mongodb.MongoClient.connect("mongodb://mongo-dev1:27017/test", function(err, db) { if (err) { throw err; } var calls = []; var col =
var mongodb = require("mongodb");
var async = require("async");
mongodb.MongoClient.connect("mongodb://mongo-dev1:27017/test", function(err, db) {
if (err) { throw err; }
var calls = [];
var col = db.collection("test");
var count = 10000;
for(var i = 0; i < count; i++) {
(function(i) {
calls.push(function(cb) {
console.time("update_" + i);
col.update({ i : i }, { i : i }, { upsert : true }, function(err) {
console.timeEnd("update_" + i);
cb(err);
});
});
})(i);
}
async.parallel(calls, function(err) {
if (err) { throw err; }
console.log("done");
});
});
var mongodb=require(“mongodb”);
var async=require(“异步”);
mongodb.MongoClient.connect(“mongodb://mongo-dev1:27017/test,函数(err,db){
if(err){throw err;}
var调用=[];
var col=数据库收集(“测试”);
var计数=10000;
对于(变量i=0;i
如果我运行该脚本,它将失败并出现以下错误MongoError:server mongo-dev1:27017 sockets closed
mongodb本身的日志输出是
SocketException处理请求,关闭客户端连接:9001套接字异常[SEND_ERROR]服务器[192.168.1.111:53556]
我不知道是什么机制导致套接字关闭。我认为等式的节点端挂起了,因为我的事件计时显示节点关闭事件发生在mongodb日志中SocketException之前的毫秒。我进入了mongodb
包,进入mongodb核心
,做了一些console.log
,事件的发起人是在TCP.close(net.js:485:12)
。这告诉我套接字本身正在关闭。基于此,它确实感觉linux本身正在关闭套接字或mongoDB主机盒,而不是Node或mongoDB在做这件事。但我不知道如何证明这一点
以下是我考虑的第一组选项,但已排除:
socketTimeoutMS
选项验证了这一点。如果我传递了一些小消息,我将得到超时错误db.serverStatus().connections
监视MongoDB replset上的连接,我仍然有大量可用的连接使用节点10、节点12和MongoDB 2.6时,我在重载下遇到了相同的问题,但是在深入研究MongoDB驱动程序时,我发现socketTimeout和connectTimeout的默认值设置为30000毫秒 把它们都养大解决了我的问题:
mongodb://m1.url.xyz:27017,m2.url.xyz:27017/test?replicaSet=myset&connectTimeoutMS=300000&socketTimeoutMS=300000&readPreference=secondary
(确保ulimit设置和net.ipv4.tcp_keepalive_时间针对mongodb进行了优化)
当通过网络连接到副本集并在数据库初始化脚本中快速发出大量查询时,我遇到了同样的问题 当在同一台计算机上连接到mongodb的单个实例时,这是正常的,但在网络上,即使副本集的延迟只有2-3ms,也会抛出套接字关闭错误 我还将两台计算机上的保持活动时间更改为注册表中的120。MongoDB 3.0.6服务器位于Windows server 2012上,应用程序计算机位于Windows 10上 然后我尝试了,但没有效果(首先在副本集中重新启动mongod服务) 然后,我将
?connectTimeoutMS=120000&socketTimeoutMS=120000
部分添加到查询字符串中,并通过网络成功地创建了副本集
在查看选项文档时,我发现单实例服务器的默认超时为30000ms,而副本集的默认超时为0ms
在:
请参见:复制设置级别选项
socketOptions.connectTimeoutMS{Number,默认值:0}TCP连接超时设置。
socketOptions.socketTimeoutMS{Number,默认值:0}TCP套接字超时设置。
这是node.js驱动程序的文档。我在mongoose文档中找不到关于插座和连接超时的信息,只有6-7个其他选项。我目前假设mongoose将通过逐字传递您指定的选项,而不是仅将某些选项列为白名单。然后,您可以在选项对象中指定超时,而不是在连接字符串中指定超时。我偶尔会在生产中遇到相同的异常(使用Mongo 3.0.3副本集)。到目前为止,我还没有找到解决办法。一个观察结果是,当主服务器负载较重时,这些异常更可能发生……这与我的观察结果类似。如果我在我们的实时服务器上执行此测试,那么在我开始关闭套接字之前,并行的阈值大约为1000,而在没有潜在负载的开发环境中,这个阈值大约为7000。我希望MongoDB团队中的某个人会对此有所了解。我个人认为MongoDB需要更好地收集触发每个副本集故障转移的数据。我希望有一个简单的命令,在Mongo做出故障转移决定时转储所有关键资源的状态。现在很难判断某个特定的硬件资源是否存在瓶颈,或者网络故障或一些疯狂的查询等等。我有一个非常类似的情况,即相同的套接字关闭问题,并且一直无法找到一个好的解决方案