可靠地重新连接到MongoDB

Mer*_*erc 26 mongodb node.js

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

我有一个使用MongoDB的节点应用程序.我遇到的问题是,如果MongoDB服务器由于任何原因而关闭,则应用程序不会重新连接.为了做到这一点,我将测试基于此官方教程中的代码.

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)
});
Run Code Online (Sandbox Code Playgroud)

想法是运行此脚本,然后停止mongod,然后重新启动它.那么,我们走了:

测试1:停止mongod 10秒

停止MongoDb 10秒会产生预期的结果:它将停止运行10秒的查询,然后在服务器返回ip后运行所有查询

测试2:停止mongod 30秒

在30秒之后,我开始得到:

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

{ [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' }
Run Code Online (Sandbox Code Playgroud)

麻烦的是,从此开始,当我重新启动mongod时,连接不会重新建立.

解决方案?

这个问题有解决方案吗?如果是这样,你知道它是什么吗?一旦我的应用程序开始呕吐"拓扑被破坏",让一切恢复工作的唯一方法是重新启动整个应用程序......

Gaa*_*far 27

有两个连接选项可控制连接失败后mongo nodejs驱动程序重新连接的方式

  • reconnectTries:尝试重新连接#times(默认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)
    });
Run Code Online (Sandbox Code Playgroud)

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

旁注:如果要阻止应用程序/请求等到重新连接期限到期,则必须通过该选项bufferMaxEntries: 0.这样做的代价是在短暂的网络中断期间请求也会中止.


Jav*_*ero 5

默认情况下,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) {

    });
Run Code Online (Sandbox Code Playgroud)


Nic*_*aly 5

package.json: "mongodb": "3.1.3"

重新连接现有连接

要为预先建立的连接微调重新连接配置,可以修改reconnectTries/ reconnectInterval选项(此处为默认值和更多文档)。

重新连接初始连接

对于初始连接,如果遇到错误,mongo客户端不会重新连接(请参阅下文)。我相信应该,但是与此同时,我已经使用该库(使用指数退避策略)创建了以下变通方法promise-retry

const promiseRetry = require('promise-retry')
const MongoClient = require('mongodb').MongoClient

const options = {
  useNewUrlParser: true,
  reconnectTries: 60,
  reconnectInterval: 1000,
  poolSize: 10,
  bufferMaxEntries: 0
}

const promiseRetryOptions = {
  retries: options.reconnectTries,
  factor: 1.5,
  minTimeout: options.reconnectInterval,
  maxTimeout: 5000
}

const connect = (url) => {
  return promiseRetry((retry, number) => {
    console.log(`MongoClient connecting to ${url} - retry number: ${number}`)
    return MongoClient.connect(url, options).catch(retry)
  }, promiseRetryOptions)
}

module.exports = { connect }
Run Code Online (Sandbox Code Playgroud)

Mongo初始连接错误: failed to connect to server [db:27017] on first connect