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
Ответы
Ответ 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
Я решил эту проблему:
- обеспечение монго работает
- перезапуск моего сервера
Ответ 16
Вам нужно перейти в меню " Подключиться " и нажать на подменю " Подключиться к... ". Откроется новое окно сообщества MongoDB Compass, через которое вы сможете снова подключиться.