Подтвердить что ты не робот

MongoError: Топология была уничтожена

У меня есть служба REST, встроенная в node.js с Restify and Mongoose и mongoDB с коллекцией, содержащей около 30 000 документов обычного размера. У меня есть служба node, работающая через pmx и pm2.

Вчера, неожиданно, node начал обрезать ошибки с сообщением "MongoError: топология была уничтожена", больше ничего. Я понятия не имею, что это значит и что могло бы вызвать это. там также не так много можно найти, когда Google-поиск это. Поэтому я думал, что попрошу здесь.

После перезапуска службы node, ошибки перестали поступать. У меня также есть один из них, работающих на производстве, и меня пугает, что это может произойти в любой момент времени в довольно важной части установки, работающей там...

Я использую следующие версии упомянутых пакетов:

  • mongoose: 4.0.3
  • restify: 3.0.3
  • node: 0.10.25
4b9b3361

Ответ 1

Кажется, ваше серверное соединение node с вашим экземпляром 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 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, указанную в комментариях, поскольку обновления не были установлены для ускорения сбоя или исправления

Ответ 2

Я знаю, что ответ Джейсона был принят, но у меня была та же проблема с Mongoose и нашлось, что служба, в которой размещена моя база данных, рекомендуется применять следующие настройки, чтобы сохранить связь Mongodb в производстве:

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

Я надеюсь, что этот ответ может помочь другим людям, имеющим ошибки "Топология".

Ответ 3

Эта ошибка вызвана тем, что драйвер mongo отключил соединение по какой-либо причине (например, сервер был недоступен).

По умолчанию mongoose попытается повторно подключиться на 30 секунд, а затем прекратить повторную попытку и бросить ошибки навсегда до перезапуска.

Вы можете изменить это, отредактировав эти 2 поля в параметрах подключения

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

документация о возможностях подключения

Ответ 4

В моем случае эта ошибка была вызвана 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
});

Ответ 5

Просто незначительное дополнение к ответу Гаафара, это дало мне предупреждение об устаревании. Вместо объекта на сервере, вот так:

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

Это может пойти на объекте верхнего уровня. По сути, просто извлеките его из объекта сервера и поместите в объект параметров следующим образом:

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

Ответ 6

"Топология уничтожена" может быть вызвана отключением mongoose перед созданием индексов документов mongo, согласно этому комментарию

Чтобы убедиться, что все модели имеют свои индексы, построенные перед отключением, вы можете:

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

await mongoose.disconnect();

Ответ 7

У меня была такая же ошибка. Наконец, я обнаружил, что у меня есть некоторая ошибка в моем коде. Я использую баланс нагрузки для двух серверов nodejs, но я просто обновляю код одного сервера.

Я меняю сервер 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 для строки подключения]

Ответ 8

Я встречал это в среде 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
};

Ответ 9

Я получил эту ошибку, когда создавал новую базу данных в сообществе MongoDb Compass. Проблема была с моим Mongod, он не работал. В качестве исправления я должен был выполнить команду Mongod, как описано выше.

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

Я смог создать базу данных после выполнения этой команды.

Надеюсь, поможет.

Ответ 10

Комментарий Себастьяна к ответу Адриена нуждается в большем внимании, он мне помог, но этот комментарий иногда можно игнорировать, поэтому вот решение:

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

Ответ 11

Я боролся с этим в течение некоторого времени - как вы можете видеть из других ответов, проблема может быть совсем другой.

Самый простой способ выяснить, что является причиной этого, это включить loggingLevel: info в опциях

Ответ 12

Вот что я сделал, все отлично работает. Проблема исчезла после добавления указанных ниже параметров.

const dbUrl = "mongodb://localhost:27017/sampledb";
const options =  { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000, useNewUrlParser: true }
mongoose.connect(dbUrl,options, function(
  error
) {
  if (error) {
    console.log("mongoerror", error);
  } else {
    console.log("connected");
  }

});

Ответ 13

В моем случае эта ошибка была вызвана тем же экземпляром сервера, который уже работал в фоновом режиме.

Странно то, что когда я запустил свой сервер без предварительного уведомления, на котором уже запущен сервер, консоль не показала ничего вроде "что-то использует порт xxx". Я мог бы даже загрузить что-то на сервер. Итак, мне потребовалось довольно много времени, чтобы найти эту проблему.

Более того, после закрытия всех приложений, которые я могу себе представить, я все еще не мог найти процесс, использующий этот порт, в моем мониторе активности Mac. Я должен использовать lsof для отслеживания. Виновник не удивил - это процесс узла. Однако с помощью идентификатора PID, показанного в терминале, я обнаружил, что номер порта на мониторе отличается от номера порта, используемого моим сервером.

В общем, уничтожение всех процессов узла может решить эту проблему напрямую.

Ответ 14

Вам нужно перезапустить mongo, чтобы устранить ошибку топологии, а затем просто изменить некоторые параметры mongoose или mongoclient, чтобы преодолеть эту проблему:

var mongoOptions = {
    useMongoClient: true,
    keepAlive: 1,
    connectTimeoutMS: 30000,
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 5000,
    useNewUrlParser: true
}

mongoose.connect(mongoDevString,mongoOptions);

Ответ 15

Я решил эту проблему:

  1. обеспечение монго работает
  2. перезапуск моего сервера

Ответ 16

Вам нужно перейти в меню " Подключиться " и нажать на подменю " Подключиться к... ". Откроется новое окно сообщества MongoDB Compass, через которое вы сможете снова подключиться.