Как убедиться, что Node.js продолжает работать после разрыва соединения с MonogDB?

У меня есть промежуточное программное обеспечение для обработки ошибок в Express, которое пытается перехватить все входящие ошибки:

app.use(function(err, req, res, next){
  console.error(err.stack);
  res.status(500);
  res.render('500.jade');
});

Но по какой-то причине, когда я закрываю mongod процесс, мое приложение вылетает со следующей трассировкой стека:

Error: failed to connect to [localhost:27017]
    at null.<anonymous> (/<hidden>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:540:74)
    at EventEmitter.emit (events.js:106:17)
    at null.<anonymous> (/<hidden>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:140:15)
    at EventEmitter.emit (events.js:98:17)
    at Socket.<anonymous> (/<hidden>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:478:10)
    at Socket.EventEmitter.emit (events.js:95:17)
    at net.js:441:14
    at process._tickCallback (node.js:415:13)

Process finished with exit code 8

Я попытался использовать следующую конфигурацию, но это не помогло мне:

var options = {
  server:{
    auto_reconnect: true,
      poolSize: 10,
      socketOptions:{
      keepAlive: 1
    }
  },
  db: {
    numberOfRetries: 10,
    retryMiliSeconds: 1000
  }
}

mongoose.connect(config.db, options);

Кто-то может спросить: "Почему вы хотите, чтобы ваше приложение работало, если оно больше не работает без подключения к базе данных?". Я не хочу, чтобы он падал и перезагружался. Модули Supervisor и Forever, по-видимому, перестают пытаться переподключиться после определенного числа попыток, в результате чего ваше приложение зависает в аварийном состоянии.

В идеале, когда происходит сбой MongoDB, я хотел бы показать пользователям страницу ошибки 500.jade, а сервер должен пытаться переподключаться к базе данных каждые 10 секунд. После повторного подключения возобновите все обычные операции.

РЕДАКТИРОВАТЬ: Ни одно из решений, опубликованных ниже, не работает для меня, за исключением доменов.

3 ответа

Решение

Попробуйте инициализировать БД в домене, который бы ловил ошибки без сбоев

var d = require('domain').create();

d.on('error', function(er) {
    console.log('Oh no, something wrong with DB');
});

d.run(function() {
    mongoose.connect(config.db, options);
});

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

Это то, что я делаю, чтобы справиться с ошибками Mongo - добавьте это как промежуточное ПО. Он также попытается снова подключиться.

// Handler in case Mongo  goes down
app.use(function(req, res, next) {
  // We lost connection!
  if (1 !== mongoose.connection.readyState) {

    // Reconnect if we can
    mongoose.connect(config.db, options);
    res.status(503);
    throw new Error('Mongo not available');
  }
  next();

});

Это предполагает, что у вас есть стандартный 50-кратный обработчик ошибок, который покажет пользователю приятную страницу.

Повторное соединение существует для следующего пользователя / загрузки страницы, чтобы проверить, не было ли оно резервного копирования. Работает хорошо.

Драйвер MongoDB выдает событие "close", когда соединение теряется. Вы можете нажать на это событие, пометить БД как недоступную и написать любую логику, основанную на этом.

db.on('close', function() {
  // handle the disconnect
  dbAvailable = false;
});

У меня есть небольшой модуль NPM, который обрабатывает это, если вы заинтересованы: https://npmjs.org/package/mongoconnect

Другие вопросы по тегам