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



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



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



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



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




  • Мангуст: 4.0.3

  • restify: 3.0.3

  • узел: 0.10.25

870   12  

12 ответов:

похоже, что соединение вашего сервера узлов с вашим экземпляром 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);
}

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

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

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

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

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

по умолчанию Мангуст будет пытаться повторно подключиться в течение 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 
        } 
    }
);

параметры подключения документация

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

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

Он может перейти на объект верхнего уровня. В принципе, просто выньте его из объекта сервера и поместите его в объект options следующим образом:

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

у меня тоже была такая же ошибка. Наконец, я обнаружил, что у меня есть некоторые ошибки в моем коде. Я использую баланс нагрузки для двух серверов 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 для подключения строка]

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

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

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

await mongoose.disconnect();

Я встретил это в среде kubernetes/minikube + nodejs + Мангуст. Проблема заключалась в том, что служба 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 и подобных подобных сайтах)

в моем случае, эта ошибка была вызвана db.close(); из раздела 'await' внутри 'async'

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

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

C:\Program Files\MongoDB\Server.6\bin>mongod

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

надеюсь, что это помогает.

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

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

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

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

Я решил эту проблему следующим образом:

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

вы должны пойти в " Connect меню" и нажмите на "подключиться ..." подменю. Это откроет новый MongoDB Compass Community окно, через которое можно снова соединить.

Comments

    Ничего не найдено.