mongoError:拓扑已被破坏

dre*_*gan 148 mongoose mongodb node.js restify pm2

我有一个使用Restify和Mongoose构建在node.js中的REST服务和一个带有大约30.000个常规文档的集合的mongoDB.我的节点服务通过pmx和pm2运行.

昨天,突然,节点开始消除错误消息"MongoError:拓扑被破坏",仅此而已.我不知道这是什么意思,什么可能触发这个.谷歌搜索时也没有太多东西可以找到.所以我想我会问这里.

今天重新启动节点服务之后,错误就停止了.我也有其中一个正在运行中,它让我感到害怕,这可能会在任何给定的时间发生在运行那里的设置的一个非常重要的部分......

我正在使用以下版本的提到的包:

  • 猫鼬:4.0.3
  • 解决:3.0.3
  • 节点:0.10.25

Jas*_*ols 95

这似乎意味着您的节点服务器与MongoDB实例的连接在尝试写入时已被中断.

看一下产生该错误Mongo源代码

Mongos.prototype.insert = function(ns, ops, options, callback) {
    if(typeof options == 'function') callback = options, options = {};
    if(this.s.state == DESTROYED) return callback(new MongoError(f('topology was destroyed')));
    // Topology is not connected, save the call in the provided store to be
    // Executed at some point when the handler deems it's reconnected
    if(!this.isConnected() && this.s.disconnectHandler != null) {
      callback = bindToCurrentDomain(callback);
      return this.s.disconnectHandler.add('insert', ns, ops, options, callback);
    }

    executeWriteOperation(this.s, 'insert', ns, ops, options, callback);
}
Run Code Online (Sandbox Code Playgroud)

这似乎与评论中引用的Sails问题无关,因为没有安装任何升级来促成崩溃或"修复"

  • 我有同样的问题,几乎每个星期都会发生,并关闭与mongo一起工作的应用程序,这是我产生的一些问题还是这是猫鼬的问题? (2认同)

Adr*_*oly 80

我知道Jason的答案已被接受,但我遇到了与Mongoose相同的问题,并发现托管我的数据库的服务建议应用以下设置以保持Mongodb的连接在生产中保持活跃状态​​:

var options = {
  server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
  replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
};
mongoose.connect(secrets.db, options);
Run Code Online (Sandbox Code Playgroud)

我希望这个回复可以帮助其他人"拓扑被破坏"的错误.

  • 使用版本3.4.2中的Mongo驱动程序,这些选项需要位于顶层:选项:{keepAlive:1,connectTimeoutMS:30000,reconnectTries:30,reconnectInterval:5000} (8认同)
  • 这对我来说没有解决问题.实际上我最终将keepAlive增加到了30000,这对我的帮助非常大.即使我仍然偶尔会遇到拓扑错误. (4认同)

Gaa*_*far 69

此错误是由于mongo驱动程序因任何原因丢弃连接(例如服务器已关闭).

默认情况下,mongoose将尝试重新连接30秒,然后停止重试并永远抛出错误,直到重新启动.

您可以通过编辑连接选项中的这两个字段来更改此设置

mongoose.connect(uri, 
    { server: { 
        // sets how many times to try reconnecting
        reconnectTries: Number.MAX_VALUE,
        // sets the delay between every retry (milliseconds)
        reconnectInterval: 1000 
        } 
    }
);
Run Code Online (Sandbox Code Playgroud)

连接选项文档

  • 您现在不需要在服务器对象下提供这些选项.它直接转到选项对象. (4认同)
  • 是的.从技术上讲,接受的答案回答了问题,但这是避免讨论情景的正确方法. (3认同)
  • 使用版本3.4.2中的Mongo驱动程序,这些选项需要位于顶层:options:{keepAlive:1,connectTimeoutMS:30000,reconnectTries:30,reconnectInterval:2000} (3认同)
  • 只是想补充说最新版本的mongoose在顶层有这些选项,所以不需要添加`server:{`等. (3认同)

Car*_*uez 16

在我的情况下,这个错误是由db.close();'async'中的'await'部分引起的

MongoClient.connect(url, {poolSize: 10, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000}, function(err, db) {
    // Validate the connection to Mongo
    assert.equal(null, err);    
    // Query the SQL table 
    querySQL()
    .then(function (result) {
        console.log('Print results SQL');
        console.log(result);
        if(result.length > 0){

            processArray(db, result)
            .then(function (result) {
                console.log('Res');
                console.log(result);
            })
            .catch(function (err) {
                console.log('Err');
                console.log(err);
            })
        } else {
            console.log('Nothing to show in MySQL');
        }
    })
    .catch(function (err) {
        console.log(err);
    });
    db.close(); // <--------------------------------THIS LINE
});
Run Code Online (Sandbox Code Playgroud)

  • 你的解决方案是将`db.close`移动到`then`块,对吗? (3认同)
  • 在卡洛斯的案例中,我猜这次关闭发生在其他事情之前.我的情况类似:我关闭它后访问了数据库.如果Mongo开发人员可以产生更明确的错误消息,那就太好了."拓扑破碎"听起来像一个内部注释. (2认同)

cod*_*ire 12

这只是Gaafar答案的一小部分内容,它给了我一个折旧警告.而不是在服务器对象上,如下所示:

MongoClient.connect(MONGO_URL, {
    server: {
        reconnectTries: Number.MAX_VALUE,
        reconnectInterval: 1000
    }
});
Run Code Online (Sandbox Code Playgroud)

它可以进入顶级对象.基本上,只需将其从服务器对象中取出并将其放在options对象中,如下所示:

MongoClient.connect(MONGO_URL, {
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000
});
Run Code Online (Sandbox Code Playgroud)


gol*_*das 7

根据此注释,“拓扑已被破坏”可能是由在创建mongo文档索引之前断开猫鼬连接引起的

为了确保在断开连接之前已建立所有模型的索引,您可以:

await Promise.all(mongoose.modelNames().map(model => mongoose.model(model).ensureIndexes()));

await mongoose.disconnect();
Run Code Online (Sandbox Code Playgroud)