可靠地重新连接到MongoDB

更新:我在驱动程序上使用2.1版本,对3.2

我有一个使用MongoDB的节点应用程序。 我遇到的问题是,如果MongoDB服务器出于任何原因closures,应用程序不会重新连接。 为了做到这一点,我在这个官方教程中的代码基础上进行testing。

var MongoClient = require('mongodb').MongoClient , f = require('util').format; MongoClient.connect('mongodb://localhost:27017/test', // Optional: uncomment if necessary // { db: { bufferMaxEntries: 3 } }, function(err, db) { var col = db.collection('t'); setInterval(function() { col.insert({a:1}, function(err, r) { console.log("insert") console.log(err) col.findOne({}, function(err, doc) { console.log("findOne") console.log(err) }); }) }, 1000) }); 

这个想法是运行这个脚本,然后停止mongod,然后重新启动它。 那么,我们走吧:

testing1:停止10秒钟

停止MongoDb 10秒钟会产生所需的结果:它将停止运行那些10秒的查询,然后一旦服务器回到ip就运行所有的查询

testing2:停止mongod 30秒

正好30秒后,我开始得到:

 { [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' } insert { [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' } 

麻烦的是,从这以后,当我重启mongod时,连接不被重新build立

解决scheme?

这个问题有解决办法吗? 如果是这样,你知道它是什么吗? 一旦我的应用程序开始呕吐“拓扑被破坏”,唯一的方法让所有的工作再次是通过重新启动整个应用程序…

有两个连接选项可以控制连接失败后mongo nodejs驱动程序如何重新连接

  • reconnectTries:尝试重新连接#次(默认30次)
  • reconnectInterval:服务器将在重试之间等待#毫秒(默认1000毫秒)

mongo驱动程序文档的参考

这意味着mongo会默认尝试连接30次,每次重试前等待1秒钟。 这就是为什么你在30秒后开始看到错误。

你应该根据你的需要来调整这两个参数。

 var MongoClient = require('mongodb').MongoClient, f = require('util').format; MongoClient.connect('mongodb://localhost:27017/test', { // retry to connect for 60 times reconnectTries: 60, // wait 1 second before retrying reconnectInterval: 1000 }, function(err, db) { var col = db.collection('t'); setInterval(function() { col.insert({ a: 1 }, function(err, r) { console.log("insert") console.log(err) col.findOne({}, function(err, doc) { console.log("findOne") console.log(err) }); }) }, 1000) }); 

这将尝试60次,而不是默认的30,这意味着你将开始看到60秒后,当它停止尝试重新连接的错误。

旁注:如果你想阻止应用程序/请求等待,直到重新连接期限到期,你必须通过选项bufferMaxEntries: 0 。 这样做的代价是在短暂的networking中断期间请求也被中止。

默认情况下,Mongo驱动程序将尝试重新连接30次,每秒一次。 之后,它不会再尝试重新连接。

您可以将重试次数设置为Number.MAX_VALUE,以保持“几乎永远”重新连接:

  var connection = "mongodb://127.0.0.1:27017/db"; MongoClient.connect(connection, { server : { reconnectTries : Number.MAX_VALUE, autoReconnect : true } }, function (err, db) { }); 

行为可能会因驱动程序的不同版本而异。 你应该提到你的驱动版本。

驱动版本:2.2.10(最新)mongo db版本:3.0.7

下面的代码将延长mongod可以回来的时间。

 var MongoClient = require('mongodb').MongoClient , f = require('util').format; function connectCallback(err, db) { var col = db.collection('t'); setInterval(function() { col.insert({a:1}, function(err, r) { console.log("insert") console.log(err) col.findOne({}, function(err, doc) { console.log("findOne") console.log(err) }); }) }, 1000) } var options = { server: { reconnectTries: 2000,reconnectInterval: 1000 }} MongoClient.connect('mongodb://localhost:27017/test',options,connectCallback); 

第二个参数可以用来传递服务器选项。

这是因为它可能超过了重试连接限制。 重试次数后,它将销毁TCP连接并变为空闲状态。 所以为了增加重试的次数,如果增加连接重试之间的差距会更好。

使用下面的选项:

 retryMiliSeconds {Number, default:5000}, number of milliseconds between retries. numberOfRetries {Number, default:5}, number of retries off connection. 

有关更多详细信息,请参阅此链接https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html

解:

 MongoClient.connect("mongodb://localhost:27017/integration_test_?", { db: { native_parser: false, retryMiliSeconds: 100000, numberOfRetries: 100 }, server: { socketOptions: { connectTimeoutMS: 500 } } }, callback)