2015-06-18 2 views
48

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

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

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

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

  • мангуста: 4.0.3
  • restify: 3.0.3
  • узел: 0.10.25
+0

Какую версию узла, мангуста и рефите вы используете? – SarathMS

+0

добавил информацию в вопрос – dreagan

+0

У меня проблемы с использованием только драйвера mongodb :( – 0x8890

ответ

33

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

Это не по всей видимости, связано с вопросом парусов цитируемой в комментариях, так как не было установлено ни одного обновления, чтобы осадить аварии или «исправить»

52

Я знаю, что ответ Джейсона был принят, но у меня была такая же проблема с Мангуста и обнаружили, что 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); 

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

+4

Это не исправить проблему для меня. На самом деле, я увеличил свой уровень keepAlive до 30000, что очень помогло. Даже при том, что я все еще получаю случайную ошибку топологии, приходите еще. – ifightcrime

+1

с использованием драйвера Mongo версии 3.4.2 эти параметры должны быть на верхнем уровне : варианты: { Keepalive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000 }. – Shide

1

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

26

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

По умолчанию 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 
     } 
    } 
); 

connection options documentation

+2

Да Технически принятый ответ отвечает на поставленный вопрос, но это правильный путь, чтобы избежать сценария ˙U обсуждение. – kingdango

+1

с использованием драйвера Mongo версии 3.4.2 эти параметры должны быть на верхнем уровне: options: {keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 2000} – Shide

+0

Чтобы уточнить, согласно [документации Node MongoDB Driver] (http://mongodb.github.io/node-mongodb-native/2.1/api/Server.html), по умолчанию сервер будет пытаться повторно подключиться 30 раз, с одной секундой друг от друга между каждой попыткой. – Boaz

0

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

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

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

MongoClient.connect(MONGO_URL, { 
    reconnectTries: Number.MAX_VALUE, 
    reconnectInterval: 1000 
}); 
Смежные вопросы