如何防止node.js崩溃?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (26)

根据我的经验,php服务器会向日志或服务器端抛出异常,但node.js只是简单地崩溃。围绕我的代码,尝试捕获也不起作用,因为一切都是异步完成的。我想知道其他人在他们的生产服务器上做什么。

提问于
用户回答回答于

如果有人正在使用其他声明的答案,请阅读Node Docs:

请注意uncaughtException是一种非常粗糙的异常处理机制,将来可能会删除。

因此,在仔细研究之后,我终于想出了Node文档本身的建议:

不要用它,用它domains带着cluster相反。如果你真的用uncaughtException,在每个未处理的异常之后重新启动应用程序!

我们实际上所做的是对触发错误的请求发送错误响应,同时让其他人在正常时间内完成,并停止监听该工作人员中的新请求。

通过这种方式,域的使用与集群模块紧密相连,因为主进程可以在工作人员遇到错误时分叉一个新的工作人员。请参阅下面的代码,以理解我的意思。

Domain,以及将我们的程序分离为多个工作进程的弹性使用Cluster,我们可以更恰当地反应,更安全地处理错误。

var cluster = require('cluster');
var PORT = +process.env.PORT || 1337;

if(cluster.isMaster) 
{
   cluster.fork();
   cluster.fork();

   cluster.on('disconnect', function(worker) 
   {
       console.error('disconnect!');
       cluster.fork();
   });
} 
else 
{
    var domain = require('domain');
    var server = require('http').createServer(function(req, res) 
    {
        var d = domain.create();
        d.on('error', function(er) 
        {
            //something unexpected occurred
            console.error('error', er.stack);
            try 
            {
               //make sure we close down within 30 seconds
               var killtimer = setTimeout(function() 
               {
                   process.exit(1);
               }, 30000);
               // But don't keep the process open just for that!
               killtimer.unref();
               //stop taking new requests.
               server.close();
               //Let the master know we're dead.  This will trigger a
               //'disconnect' in the cluster master, and then it will fork
               //a new worker.
               cluster.worker.disconnect();

               //send an error to the request that triggered the problem
               res.statusCode = 500;
               res.setHeader('content-type', 'text/plain');
               res.end('Oops, there was a problem!\n');
           } 
           catch (er2) 
           {
              //oh well, not much we can do at this point.
              console.error('Error sending 500!', er2.stack);
           }
       });
    //Because req and res were created before this domain existed,
    //we need to explicitly add them.
    d.add(req);
    d.add(res);
    //Now run the handler function in the domain.
    d.run(function() 
    {
        //You'd put your fancy application logic here.
        handleRequest(req, res);
    });
  });
  server.listen(PORT);
} 

尽管Domain正在等待废弃,并将随着Node文档中所述的新替换的到来而被移除。

此模块正在挂起弃用。一旦替换API完成,这个模块将被完全废弃。绝对必须具备域所提供的功能的用户可能暂时依赖它,但将来应该不得不迁移到不同的解决方案。

但是,在新的替代方案未引入之前,Node文档建议的唯一好解决方案是使用集群的域。

用户回答回答于

我把这段代码放在我的Required语句和全局声明下面:

process.on('uncaughtException', function (err) {
  console.error(err);
  console.log("Node NOT Exiting...");
});

扫码关注云+社区