可靠地重新连接到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)