如何防止 node.js 崩溃?尝试捕捉不起作用 [英] How do I prevent node.js from crashing? try-catch doesn't work

查看:16
本文介绍了如何防止 node.js 崩溃?尝试捕捉不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

From my experience, a php server would throw an exception to the log or to the server end, but node.js just simply crashes. Surrounding my code with a try-catch doesn't work either since everything is done asynchronously. I would like to know what does everyone else do in their production servers.

推荐答案

PM2

首先,我强烈建议为 Node.js 安装 PM2.PM2 非常擅长处理崩溃和监控 Node 应用程序以及负载平衡.每当它崩溃、因任何原因停止甚至服务器重新启动时,PM2 都会立即启动 Node 应用程序.因此,如果有一天即使在管理我们的代码之后,应用程序崩溃了,PM2 也可以立即重新启动它.欲了解更多信息,安装和运行 PM2

First of all, I would highly recommend installing PM2 for Node.js. PM2 is really great at handling crash and monitoring Node apps as well as load balancing. PM2 immediately starts the Node app whenever it crashes, stops for any reason or even when server restarts. So, if someday even after managing our code, app crashes, PM2 can restart it immediately. For more info, Installing and Running PM2

其他答案真的很疯狂,您可以在 http 阅读 Node 自己的文档://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception

Other answers are really insane as you can read at Node's own documents at http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception

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

If someone is using other stated answers read Node Docs:

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

Note that uncaughtException is a very crude mechanism for exception handling and may be removed in the future

现在回到我们防止应用本身崩溃的解决方案.

Now coming back to our solution to preventing the app itself from crashing.

所以在经历了之后,我终于想出了 Node 文档本身的建议:

So after going through I finally came up with what Node document itself suggests:

不要使用 uncaughtException,而是使用 domainscluster.如果您确实使用了 uncaughtException,请在每个未处理的异常后重新启动您的应用程序!

Don't use uncaughtException, use domains with cluster instead. If you do use uncaughtException, restart your application after every unhandled exception!

DOMAIN集群

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

What we actually do is send an error response to the request that triggered the error, while letting the others finish in their normal time, and stop listening for new requests in that worker.

通过这种方式,域使用与集群模块密切相关,因为当一个工作进程遇到错误时,主进程可以派生一个新的工作进程.请参阅下面的代码以了解我的意思

In this way, domain usage goes hand-in-hand with the cluster module, since the master process can fork a new worker when a worker encounters an error. See the code below to understand what I mean

通过使用 Domain,以及使用 Cluster 将我们的程序分成多个工作进程的弹性,我们可以做出更适当的反应,并以更高的安全性处理错误.

By using Domain, and the resilience of separating our program into multiple worker processes using Cluster, we can react more appropriately, and handle errors with much greater safety.

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!
');
           } 
           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 文档中所述

Though Domain is pending deprecation and will be removed as the new replacement comes as stated in Node's Documentation

此模块正在等待弃用.一旦替代 API 完成,该模块将被完全弃用.绝对必须拥有域提供的功能的用户可能暂时依赖它,但预计将来必须迁移到不同的解决方案.

This module is pending deprecation. Once a replacement API has been finalized, this module will be fully deprecated. Users who absolutely must have the functionality that domains provide may rely on it for the time being but should expect to have to migrate to a different solution in the future.

但在没有引入新的替代品之前,Domain with Cluster 是 Node Documentation 建议的唯一好的解决方案.

But until the new replacement is not introduced, Domain with Cluster is the only good solution what Node Documentation suggests.

为了深入了解DomainCluster阅读

https://nodejs.org/api/domain.html#domain_domain(稳定性:0 - 已弃用)

https://nodejs.org/api/cluster.html

感谢@Stanley Luo 为我们分享了关于集群和域的精彩深入解释

Thanks to @Stanley Luo for sharing us this wonderful in-depth explanation on Cluster and Domains

集群&域

这篇关于如何防止 node.js 崩溃?尝试捕捉不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆