我在Express中有一个错误处理middlware,试图捕获所有传入的错误:
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秒继续尝试重新连接到数据库。重新连接后,恢复所有正常操作。
编辑:以下发布的解决方案均不适用于我,但域名除外。
答案 0 :(得分:5)
这是我处理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();
});
这假设您有一个标准的50x错误处理程序,它将向用户显示一个不错的页面。
重新连接用于下一个用户/页面加载,以检查它是否已备份。效果很好。
答案 1 :(得分:3)
尝试在domain中初始化数据库,以便在不崩溃的情况下捕获错误
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);
});
当一些事情崩溃时让服务器重新启动通常是一个好主意,但是因为你已经意识到这一点并且想要避免它,所以在域中包装失败的方法就是这样做。
答案 2 :(得分:0)
当连接丢失时,MongoDB驱动程序发出“关闭”事件。您可以点击此事件并将数据库标记为不可用,并根据该数据写入任何逻辑。
db.on('close', function() {
// handle the disconnect
dbAvailable = false;
});
我有一个小的NPM模块可以处理这个问题,如果你感兴趣的话:https://npmjs.org/package/mongoconnect