根据我的经验,php 服务器会向日志或服务器端抛出异常,但 node.js 只是简单地崩溃。用 try-catch 包围我的代码也不起作用,因为一切都是异步完成的。我想知道其他人在他们的生产服务器上做什么。
PM2
首先,我强烈建议安装PM2. Node.jsPM2 非常擅长处理崩溃和监控 Node 应用程序以及负载平衡。每当它崩溃、因任何原因停止甚至服务器重新启动时,PM2 都会立即启动 Node 应用程序。因此,如果有一天即使在管理我们的代码之后,应用程序崩溃了,PM2 也可以立即重新启动它。更多信息,安装和运行 PM2
Node.js
其他答案真的很疯狂,因为您可以在http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception上阅读 Node 自己的文档
如果有人使用其他声明的答案,请阅读 Node Docs:
请注意,这uncaughtException是一种非常粗糙的异常处理机制,将来可能会被删除
uncaughtException
现在回到我们防止应用程序本身崩溃的解决方案。
因此,在经历了之后,我终于想出了 Node 文档本身的建议:
不要用uncaughtException,用domainswithcluster代替。如果您确实使用uncaughtException,请在每个未处理的异常后重新启动您的应用程序!
domains
cluster
*带 *集群的 域* *
我们实际上要做的是向触发错误的请求发送错误响应,同时让其他人在正常时间完成,并停止在该工作人员中侦听新请求。
通过这种方式,域使用与集群模块密切相关,因为当一个工作人员遇到错误时,主进程可以派生一个新的工作人员。请参阅下面的代码以了解我的意思
通过使用Domain,以及使用 将我们的程序分成多个工作进程的弹性Cluster,我们可以做出更适当的反应,并以更高的安全性处理错误。
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 完成,该模块将被完全弃用。绝对必须拥有域提供的功能的用户可能暂时依赖它,但预计将来必须迁移到不同的解决方案。
但是在没有引入新的替代品之前,Domain with Cluster 是 Node Documentation 建议的唯一好的解决方案。
为了深入理解Domain和Cluster阅读
~~https://nodejs.org/api/domain.html#domain_domain~~ (Stability: 0 - Deprecated)
Stability: 0 - Deprecated
https://nodejs.org/api/cluster.html
感谢@Stanley Luo 为我们分享了关于集群和域的精彩深入解释
集群和域