MongoDB连接丢失后如何确保Node.js继续运行?

时间:2013-12-19 19:09:33

标签: node.js mongodb error-handling express mongoose

我在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秒继续尝试重新连接到数据库。重新连接后,恢复所有正常操作。

编辑:以下发布的解决方案均不适用于我,但域名除外。

3 个答案:

答案 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