Как убедиться, что 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