Tia*_*HUo 147 crash try-catch production-environment node.js
根据我的经验,php服务器会向日志或服务器端抛出异常,但node.js只是崩溃.用try-catch包围我的代码也不起作用,因为一切都是异步完成的.我想知道其他人在他们的生产服务器上做了什么.
Abd*_*rai 126
其他答案真的很疯狂,因为您可以在http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception上阅读Node自己的文档.
如果有人使用其他声明的答案,请阅读节点文档:
请注意,这
uncaughtException是一种非常粗略的异常处理机制,将来可能会被删除
PM2
首先,我会强烈建议安装PM2的Node.js.PM2非常适合处理崩溃和监控节点应用以及负载平衡.PM2会在崩溃时立即启动Node应用程序,因任何原因停止或甚至在服务器重新启动时停止.所以,如果有一天甚至在管理我们的代码之后,应用程序崩溃,PM2可以立即重启它.有关详细信息,请安装并运行PM2
现在回到我们的解决方案,以防止应用程序本身崩溃.
所以经过我终于想出了Node文档本身的建议:
不要使用
uncaughtException,使用domains带cluster代替.如果您使用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);
}
Run Code Online (Sandbox Code Playgroud)
虽然Domain正在等待弃用,但随着新的替代品的出现,将按照Node的文档中的说明进行删除
此模块正在等待弃用.更新API完成后,将完全弃用此模块.绝对必须具有域提供的功能的用户可能暂时依赖它,但是应该期望将来必须迁移到不同的解决方案.
但是,在没有引入新的替换之前,Domain with Cluster是Node Documentation建议的唯一好的解决方案.
深入了解Domain和Cluster阅读
https://nodejs.org/api/domain.html#domain_domain(Stability: 0 - Deprecated)
https://nodejs.org/api/cluster.html
感谢@Stanley Luo向我们分享了关于Cluster和Domains的这篇精彩深入的解释
hvg*_*des 75
我将此代码放在我的require语句和全局声明下:
process.on('uncaughtException', function (err) {
console.error(err);
console.log("Node NOT Exiting...");
});
Run Code Online (Sandbox Code Playgroud)
适合我.我唯一不喜欢的是我没有得到尽可能多的信息,如果我让事情崩溃.
Sea*_*ter 27
如上所述,您将找到error.stack更完整的错误消息,例如导致错误的行号:
process.on('uncaughtException', function (error) {
console.log(error.stack);
});
Run Code Online (Sandbox Code Playgroud)
Ray*_*nos 12
尝试 supervisor
npm install supervisor
supervisor app.js
Run Code Online (Sandbox Code Playgroud)
或者你可以安装forever.
所有这一切都是通过重新启动服务器崩溃时恢复服务器.
forever 可以在代码中使用,以优雅地恢复崩溃的任何进程.
该forever文件对出口/错误处理程序可靠的信息.
使用try-catch可以解决未捕获的错误,但在某些复杂的情况下,它不能正常工作,如捕获异步函数.请记住,在Node中,任何异步函数调用都可能包含潜在的应用程序崩溃操作.
使用uncaughtException是一种解决方法,但它被认为是低效的,很可能在未来的Node版本中被删除,所以不要指望它.
理想的解决方案是使用域名:http://nodejs.org/api/domain.html
要确保您的应用程序启动并运行,即使您的服务器崩溃,请使用以下步骤:
使用节点集群为每个核心分叉多个进程.因此,如果一个进程死亡,另一个进程将自动启动.查看:http://nodejs.org/api/cluster.html
使用域来捕获异步操作而不是使用try-catch或uncaught.我不是说尝试捕捉或未捕获是不好的想法!
使用forever/supervisor监控您的服务
添加守护程序以运行您的节点应用程序:http://upstart.ubuntu.com
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
83942 次 |
| 最近记录: |