如何防止node.js崩溃? 尝试赶上不起作用

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

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

如果有人正在使用其他陈述的答案阅读节点文档:

请注意, uncaughtException是exception处理的非常粗暴的机制,将来可能会被删除

所以经过我终于想出了什么Node文件本身build议:

不要使用它,而是使用cluster domains 。 如果您使用uncaughtException ,请在每次未处理的exception之后重新启动应用程序!

解决scheme是使用群集的 DOMAIN

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

通过这种方式,域使用与群集模块并行,因为当进程遇到错误时,主进程可以派发新的worker。 看下面的代码来理解我的意思

通过使用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); } 

尽pipeDomain正在等待弃用,并且将会像Node节点的文档中所述的那样被删除

此模块正在等待弃用。 一旦更换API已经完成,这个模块将被完全弃用。 绝对必须具有域提供的function的用户可能暂时依赖它,但是应该期望在将来不得不迁移到不同的解决scheme。

但是,直到没有引入新的替代品之前,Domain with Cluster是Node文档所build议的唯一的良好解决scheme。

为深入了解DomainCluster读取

https://nodejs.org/api/domain.html#domain_domainStability: 0 - Deprecated

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

感谢@Stanley Luo向我们分享了关于Cluster和Domains的精彩深入的解释

群集和域名

我把这个代码放在我的require语句和全局声明下:

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

为我工作。 我不喜欢它的唯一的东西是我没有得到那么多的信息,如果我只是让事情崩溃。

如上所述,您会发现error.stack提供了一个更完整的错误消息,例如导致错误的行号:

 process.on('uncaughtException', function (error) { console.log(error.stack); }); 

试试supervisor

 npm install supervisor supervisor app.js 

或者你可以forever安装。

所有这一切将恢复您的服务器,当它通过重新启动崩溃。

forever可以在代码中使用,以正常恢复任何崩溃的进程。

forever文档有编程上的退出/error handling的可靠信息。

使用try-catch可以解决未被捕获的错误,但是在一些复杂的情况下,不能捕获asynchronous函数等工作。 请记住,在Node中,任何asynchronous函数调用都可能包含潜在的应用程序崩溃操作。

使用uncaughtException是一种解决方法,但它被认为是低效的,并且可能在未来的Node版本中被删除,所以不要指望它。

理想的解决scheme是使用域: http : //nodejs.org/api/domain.html

要确保您的应用程序已启动并运行,即使您的服务器崩溃了,请使用以下步骤:

  1. 使用节点集群来为每个内核分配多个进程。 所以如果一个进程死了,另一个进程会自动启动。 查看: http : //nodejs.org/api/cluster.html

  2. 使用域来捕获asynchronous操作,而不是使用try-catch或uncaught。 我不是说那个试着抓住或者没有被抓住就是坏的想法!

  3. 永远使用/主pipe监控您的服务

  4. 添加守护程序来运行您的节点应用程序: http : //upstart.ubuntu.com

希望这可以帮助!

试试pm2节点模块,它是相当一致的,有很好的文档。 Node.js应用程序的生产stream程pipe理器,内置负载平衡器。 请避免uncaughtException这个问题。 https://github.com/Unitech/pm2

UncaughtException是“一个非常粗暴的机制”(如此),现在域名已被弃用。 但是,我们仍然需要一些机制来捕捉(逻辑)域的错误。 图书馆:

https://github.com/vacuumlabs/yacol

可以帮助你做到这一点。 有一点额外的写作,你可以在你的代码周围有很好的域语义!

重视工作很好:

 server.on('uncaughtException', function (req, res, route, err) { log.info('******* Begin Error *******\n%s\n*******\n%s\n******* End Error *******', route, err.stack); if (!res.headersSent) { return res.send(500, {ok: false}); } res.write('\n'); res.end(); });