可靠地重新连接到 MongoDB

新手上路,请多包涵

更新: 我在驱动程序上使用 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)
});

想法是运行这个脚本,然后停止 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' }

麻烦的是,从这里开始,当我重新启动 mongod 时,连接 没有重新建立

解决方案?

这个问题有解决办法吗?如果是这样,你知道它是什么吗?一旦我的应用程序开始吐出“拓扑已被破坏”,让一切恢复正常的唯一方法是重新启动整个应用程序……

原文由 Merc 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 932
2 个回答

有 2 个连接选项可控制连接失败后 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)
    });

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

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

原文由 gafi 发布,翻译遵循 CC BY-SA 3.0 许可协议

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 }

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

原文由 Nick Grealy 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题