首页 文章

mongoError:拓扑已被破坏

提问于
浏览
113

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

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

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

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

  • 猫鼬:4.0.3

  • restify:3.0.3

  • node:0.10.25

13 回答

  • 10

    我解决了这个问题:

    • 确保mongo正在运行

    • 重启我的服务器

  • -3

    你需要转到“ Connect " menu and click on the " Connect to ... ”子菜单 . 这会打开一个新的MongoDB Compass社区窗口,您可以通过它再次连接 .

  • 4

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

    看看Mongo source code that generates that error

    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);
    }
    

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

  • 7

    我知道杰森的答案被接受了,但是我和Mongoose有同样的问题,发现the service hosting my database recommended to apply the following settings是为了让Mongodb的连接在 生产环境 中保持活力:

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

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

  • 76

    此错误是由于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 
            } 
        }
    );
    

    connection options documentation

  • 71

    在我的情况下,此错误是由已运行后台的相同服务器实例引起的 .

    奇怪的是,当我在没有通知的情况下启动服务器时,已经有一个正在运行,控制台没有显示任何类似“正在使用端口xxx”的内容 . 我甚至可以上传一些东西到服务器 . 所以,找到这个问题我花了很长时间 .

    什么's more, after closing all the applications I can imagine, I still could not find the process which is using this port in my Mac'的活动监控 . 我必须使用 lsof 来追踪 . 罪魁祸首并不奇怪 - 这是一个节点过程 . 但是,通过终端中显示的PID,我发现监视器中的端口号与我的服务器使用的端口号不同 .

    总而言之,杀死所有节点进程可以直接解决这个问题 .

  • 2

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

    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
    });
    
  • -2

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

    MongoClient.connect(MONGO_URL, {
        server: {
            reconnectTries: Number.MAX_VALUE,
            reconnectInterval: 1000
        }
    });
    

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

    MongoClient.connect(MONGO_URL, {
        reconnectTries: Number.MAX_VALUE,
        reconnectInterval: 1000
    });
    
  • 2

    "Topology was destroyed"可能是由mongoose在创建mongo文档索引之前断开连接造成的,每this comment

    为了确保所有模型在断开连接之前都 Build 了索引,您可以:

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

    我也有同样的错误 . 最后,我发现我的代码有一些错误 . 我为两个nodejs服务器使用负载 balancer ,但我只是更新一个服务器的代码 .

    我更改了我的mongod服务器 from standalone to replication ,但我忘记对连接字符串进行相应的更新,所以我遇到了这个错误 .

    独立连接字符串: mongodb://server-1:27017/mydb 复制连接字符串: mongodb://server-1:27017,server-2:27017,server-3:27017/mydb?replicaSet=myReplSet

    详情:[mongo doc for connection string]

  • 0

    我在kubernetes / minikube nodejs mongoose环境中遇到了这个 . 问题是DNS服务出现了一种延迟 . 检查DNS已经准备好解决了我的问题 .

    const dns = require('dns');
    
    var dnsTimer = setInterval(() => {
    	dns.lookup('mongo-0.mongo', (err, address, family) => {
    		if (err) {
    			console.log('DNS LOOKUP ERR', err.code ? err.code : err);
    		} else {
    			console.log('DNS LOOKUP: %j family: IPv%s', address, family);
    			clearTimeout(dnsTimer);
    			mongoose.connect(mongoURL, db_options);
    		}
    	});
    }, 3000);
    
    
    var db = mongoose.connection;
    var db_options = {
    	autoReconnect:true,
    
    	poolSize: 20,
    	socketTimeoutMS: 480000,
    	keepAlive: 300000,
    
    	keepAliveInitialDelay : 300000,
    	connectTimeoutMS: 30000,
    	reconnectTries: Number.MAX_VALUE,
    	reconnectInterval: 1000,
    	useNewUrlParser: true
    };
    

    (db_options中的数字在stackoverflow和类似的站点上是任意的)

  • 1

    当我在MongoDb Compass社区创建一个新数据库时,我收到了这个错误 . 问题出在我的Mongod上,它没有运行 . 所以作为一个修复,我必须像前面那样运行Mongod命令 .

    C:\Program Files\MongoDB\Server\3.6\bin>mongod
    

    运行该命令后,我能够创建一个数据库 .

    希望能帮助到你 .

  • 0

    塞巴斯蒂安对阿德里安的答案的评论需要更多的关注,它帮助了我,但它是一个评论可能会被忽略 so here's a solution

    var options =  { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000 }
    mongoose.connect(config.mongoConnectionString, options, (err) => {
        if(err) {
            console.error("Error while connecting", err);
        }
    });
    

相关问题