Node.js 如何在未捕获的异常情况下优雅地重新启动NodeJS服务器?
我正在使用模块将我的请求包装到域中。在我的错误中间件中,我有以下检查:Node.js 如何在未捕获的异常情况下优雅地重新启动NodeJS服务器?,node.js,azure,iis,express,Node.js,Azure,Iis,Express,我正在使用模块将我的请求包装到域中。在我的错误中间件中,我有以下检查: if(err.domain) { //something should happen here, it's completely uncaught } else { //silly kids, I'll log this and send a 500; 上述代码片段基于express域中间件文档中的示例: //with domain-middleware app.use(require('express-domain-
if(err.domain) {
//something should happen here, it's completely uncaught
}
else {
//silly kids, I'll log this and send a 500;
上述代码片段基于express域中间件
文档中的示例:
//with domain-middleware
app.use(require('express-domain-middleware'));
app.use(app.router);
app.use(function errorHandler(err, req, res, next) {
console.log('error on request %d %s %s', process.domain.id, req.method, req.url);
console.log(err.stack);
res.send(500, "Something bad happened. :(");
if(err.domain) {
//you should think about gracefully stopping & respawning your server
//since an unhandled error might put your application into an unknown state
}
});
app.get('/error', function(req, res, next) {
db.query('SELECT happiness()', process.domain.intercept(function(rows) {
fs.readFile('asldkfjasdf', process.domain.intercept(function(contents) {
process.nextTick(process.domain.intercept(function() {
throw new Error("The individual request will be passed to the express error handler, and your application will keep running.");
}));
}));
}));
});
如果此异常发生在域之外,我不想做的是调用进程。退出(1)
(我认为实际上没有人会这样做,对吧?)。我也不想让我的应用程序处于危险状态。我宁愿只记录未捕获的异常,这样我以后就可以重构它,优雅地重新启动这个域(服务器?),然后继续工作
假设
- 此应用程序正在IIS上的Azure中运行。我要发送什么命令才能正常重启应用程序?我不知道IIS将采取什么行为,而不是永远采取什么行为。我特意用
永久性地在本地启动了这个应用程序,并观察到它在强制执行未处理的异常时自动重启——但我是在Mac上开发的,应用程序运行在Windows上。需要Windows解决方案=)
编辑:如果我对域内发生的事情和未捕获的异常有误解,请纠正我。我是来学习的 节点程序可以在spawn的帮助下像这样重新启动自身:
var exec = require('child_process').exec;
spawn('sh', ['-c', 'sleep 2; node /home/username/Desktop/MainNodeApplication.js'], {
detached: true,
stdio: ['ignore', 'ignore', 'ignore']
});
process.exit(0);
前面的代码是为了在Linux机器上使用存储在/home/username/Desktop/MainNodeApplication.js中的一个非常简单的节点脚本编写的。此代码生成另一个进程,将其与父进程分离,然后立即退出。同时,生成的进程在2秒钟内重新启动节点脚本,在我们恢复正常并确保其他实例有时间关闭之后
这并不能完全满足您的需求,但它允许您优雅地重新启动代码。您可以在启动它时传递参数,让它更好地知道它应该处于什么状态,或者将错误信息传递给用户。您可以通过在spawn arguments中向节点调用添加参数来实现这一点。在发生未捕获的异常后,您的服务器可能很容易处于错误状态,因此除了关闭服务器然后重新启动之外,没有通用的恢复方法。您不能从服务器本身内部执行此操作。相反,当异常发生时,您需要退出服务器,然后使用某种外部代理从头开始重新启动它(比如永远)。看看它们基本上都是相同的子进程,因此如果一个失败,另一个会生成,因为它是一个“新”副本,就其本身而言,几乎就像从头开始一样。