Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何在未捕获的异常情况下优雅地重新启动NodeJS服务器?_Node.js_Azure_Iis_Express - Fatal编程技术网

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)
(我认为实际上没有人会这样做,对吧?)。我也不想让我的应用程序处于危险状态。我宁愿只记录未捕获的异常,这样我以后就可以重构它,优雅地重新启动这个域(服务器?),然后继续工作

假设
  • 通过采用这种方法,更大的应用程序将不会因为一个域的不稳定性而受到影响。我可以在不终止任何其他连接的情况下重新启动。(Edit:我创建了一个路由,该路由会故意抛出未处理的异常,并在单独的选项卡中登录到应用程序。通过强制异常并永久重新启动,我还终止了“合法”会话——我猜我做错了什么)
  • 如果我只是重新启动服务器,用户将不知道发生了什么。我假设他们在刷新后会看到登录屏幕,而不知道原因。如果这是一个已处理的异常,我会向客户端发送一个JSON响应,解释发生了什么,或者将用户重定向到错误页面。当异常未处理时,处理此场景的正确方法是什么
  • 太长,读不下去了
    • 此应用程序正在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中向节点调用添加参数来实现这一点。

    在发生未捕获的异常后,您的服务器可能很容易处于错误状态,因此除了关闭服务器然后重新启动之外,没有通用的恢复方法。您不能从服务器本身内部执行此操作。相反,当异常发生时,您需要退出服务器,然后使用某种外部代理从头开始重新启动它(比如永远)。看看它们基本上都是相同的子进程,因此如果一个失败,另一个会生成,因为它是一个“新”副本,就其本身而言,几乎就像从头开始一样。