Answers:
您可以从Node自己的文档中(http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception)阅读其他答案,真是太疯狂了
如果有人在使用其他规定的答案,请阅读Node Docs:
请注意,这
uncaughtException
是异常处理的非常粗糙的机制,以后可能会删除
下午2
首先,我会强烈建议安装PM2
的Node.js
。PM2非常适合处理崩溃和监视Node应用程序以及负载平衡。每当PM2崩溃时,PM2都会立即启动Node应用程序,无论出于任何原因甚至在服务器重新启动时都会停止。因此,即使有一天即使在管理完我们的代码之后,应用程序崩溃,PM2仍可以立即重新启动它。有关更多信息,请安装和运行PM2
现在回到我们的解决方案,以防止应用程序本身崩溃。
因此,经过研究之后,我终于想到了Node文档本身的建议:
不要使用
uncaughtException
,而是使用domains
withcluster
。如果您使用uncaughtException
,请在每个未处理的异常后重新启动应用程序!
DOMAIN与丛集
我们实际上要做的是向触发错误的请求发送错误响应,同时让其他请求在正常时间内完成,并停止侦听该工作线程中的新请求。
这样,域使用与群集模块紧密结合,因为当工作进程遇到错误时,主进程可以派生新的工作进程。请参阅下面的代码以了解我的意思
通过使用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 Documentation建议的唯一好的解决方案。
供深入了解Domain
和Cluster
阅读
https://nodejs.org/api/domain.html#domain_domain(Stability: 0 - Deprecated
)
https://nodejs.org/api/cluster.html
感谢@Stanley Luo向我们分享了有关集群和域的精彩深入解释
restart your application after every unhandled exception!
如果2000个用户使用节点Web服务器来流式传输视频,而1个用户遇到异常,那么重新启动不会中断所有其他用户吗?
uncaughtException
用Domain
,Cluster
而是与之一起使用的原因,因此,如果一个用户遇到异常,那么只有他的线程从群集中删除并为他创建了一个新线程。而且您也不需要重启节点服务器。另一方面,如果您确实使用uncaughtException
过,则每次任何用户遇到问题时都必须重新启动服务器。因此,将Domain与Cluster一起使用。
domain
完全否定并取消?
我将此代码放在我的require语句和全局声明下:
process.on('uncaughtException', function (err) {
console.error(err);
console.log("Node NOT Exiting...");
});
为我工作。我唯一不喜欢的是,如果我让事情崩溃,我会得到的信息不多。
forever
或重新启动服务器更好。
尝试 supervisor
npm install supervisor
supervisor app.js
或者,您也可以安装forever
。
这一切将是通过重新启动服务器来使其崩溃时恢复服务器。
forever
可以在代码内使用,以正常恢复崩溃的任何进程。
该forever
文档以编程方式提供了有关退出/错误处理的可靠信息。
使用try-catch可能会解决未捕获的错误,但是在某些复杂的情况下,它将无法正确执行捕获异步功能之类的工作。请记住,在Node中,任何异步函数调用都可能包含潜在的应用崩溃操作。
使用uncaughtException
是一种解决方法,但是它被认为是低效的,并且可能在Node的未来版本中被删除,因此不要指望它。
理想的解决方案是使用域:http : //nodejs.org/api/domain.html
为确保您的应用程序启动并运行,甚至服务器崩溃,请使用以下步骤:
使用节点群集为每个核心分叉多个进程。因此,如果一个进程死亡,则另一个进程将自动启动。检出:http : //nodejs.org/api/cluster.html
使用域来捕获异步操作,而不是使用try-catch或未捕获。我并不是说尝试捕获或未捕获是不好的想法!
永远使用/主管来监视您的服务
添加守护程序以运行您的节点应用程序:http : //upstart.ubuntu.com
希望这可以帮助!
尝试一下pm2节点模块,它是非常一致的,并且文档丰富。带有内置负载均衡器的Node.js应用程序的生产过程管理器。请避免针对此问题的uncaughtException。 https://github.com/Unitech/pm2
UncaughtException是一种“非常粗糙的机制”(是如此),现在不推荐使用域。但是,我们仍然需要某种机制来捕获(逻辑)域周围的错误。图书馆:
https://github.com/vacuumlabs/yacol
可以帮助您做到这一点。只需编写一些额外的代码,您就可以在代码周围拥有不错的域语义!