拿什么守护你的Node.JS进程: Node出错崩溃了怎么办? foreverjs, 文摘随笔
守护进程
方案一
npm install forever https://github.com/foreverjs/forever
方案二
npm install -g supervisor
http://www.cnblogs.com/pigtail/archive/2013/01/08/2851056.html
被吐嘈的NodeJS的异常处理
许多人都有这样一种映像,NodeJS比较快; 但是因为其是单线程,所以它不稳定,有点不安全,不适合处理复杂业务; 它比较适合对并发要求比较高,而且简单的业务场景。
在Express的作者的TJ Holowaychuk的 告别Node.js一文中列举了以下罪状:
Farewell NodeJS (TJ Holowaychuk)
• you may get duplicate callbacks
• you may not get a callback at all (lost in limbo)
• you may get out-of-band errors
• emitters may get multiple “error” events
• missing “error” events sends everything to hell
• often unsure what requires “error” handlers
• “error” handlers are very verbose
• callbacks suck
其实这几条主要吐嘈了两点: node.js错误处理很扯蛋,node.js的回调也很扯蛋。
事实上呢?
事实上NodeJS里程确实有“脆弱”的一面,单线程的某处产生了“未处理的”异常确实会导致整个Node.JS的崩溃退出,来看个例子, 这里有一个node-error.js的文件:
var http = require('http');
var server = http.createServer(function (req, res) {
//这里有个错误,params 是 undefined
var ok = req.params.ok;
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
});
server.listen(8080, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8080/');
启动服务,并在地址栏测试一下发现 http://127.0.0.1:8080/ 不出所料,node崩溃了
$ node node-error
Server running at http://127.0.0.1:8080/ c:\github\script\node-error.js:5
var ok = req.params.ok;
^
TypeError: Cannot read property 'ok' of undefined
at Server.<anonymous> (c:\github\script\node-error.js:5:22)
at Server.EventEmitter.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2108:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
at Socket.socket.ondata (http.js:1966:22)
at TCP.onread (net.js:525:27)
怎么解决呢?
其实Node.JS发展到今天,如果连这个问题都解决不了,那估计早就没人用了。
使用uncaughtException
我们可以uncaughtException来全局捕获未捕获的Error,同时你还可以将此函数的调用栈打印出来,捕获之后可以有效防止node进程退出,如:
process.on('uncaughtException', function (err) {
//打印出错误
console.log(err);
//打印出错误的调用栈方便调试
console.log(err.stack);
});
这相当于在node进程内部进行守护, 但这种方法很多人都是不提倡的,说明你还不能完全掌控Node.JS的异常。
使用 try/catch
我们还可以在回调前加try/catch,同样确保线程的安全。
var http = require('http');
http.createServer(function(req, res) {
try {
handler(req, res);
} catch(e) {
console.log('\r\n', e, '\r\n', e.stack);
try {
res.end(e.stack);
} catch(e) { }
}
}).listen(8080, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8080/');
var handler = function (req, res) {
//Error Popuped
var name = req.params.name;
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello ' + name);
};
这种方案的好处是,可以将错误和调用栈直接输出到当前发生的网页上。
集成到框架中
标准的HTTP响应处理会经历一系列的Middleware(HttpModule),最终到达Handler,如下图所示:

这 些Middleware和Handler在NodeJS中都有一个特点,他们都是回调函数,而回调函数中是唯一会让Node在运行时崩溃的地方。根据这个 特点,我们只需要在框架中集成一处try/catch就可以相对完美地解决异常问题,而且不会影响其它用户的请求request。
事实上现在的NodeJS WEB框架几乎都是这么做的,如 OurJS开源博客所基于的 WebSvr
就有这么一处异常处理代码:
Line: 207
try {
handler(req, res);
} catch(err) {
var errorMsg
= '\n'
+ 'Error ' + new Date().toISOString() + ' ' + req.url
+ '\n'
+ err.stack || err.message || 'unknow error'
+ '\n'
;
console.error(errorMsg);
Settings.showError
? res.end('<pre>' + errorMsg + '</pre>')
: res.end();
}
那么不在回调中产生的错误怎么办?不必担心,其实这样的node程序根本就起不起来。
此外node自带的 cluster 也有一定的容错能力,它跟nginx的worker很类似,但消耗资源(内存)略大,编程也不是很方便,OurJS并没有采用此种设计。
守护NodeJS进程和记录错误日志
现 在已经基本上解决了Node.JS因异常而崩溃的问题,不过任何平台都不是100%可靠的,还有一些错误是从Node底层抛出的,有些异常 try/catch和uncaughtException都无法捕获。之前在运行ourjs的时侯,会偶尔碰到底层抛出的文件流读取异常,这就是一个底层 libuv的BUG,node.js在0.10.21中进行了修复。
面对这种情况,我们就应该为nodejs应用添加守护进程,让NodeJS遭遇异常崩溃以后能马上复活。
另外,还应该把这些产生的异常记录到日志中,并让异常永远不再发生。
拿什么守护你的Node.JS进程: Node出错崩溃了怎么办? foreverjs, 文摘随笔的更多相关文章
- 拿什么守护你的Node.JS进程: Node出错崩溃了怎么办?
被吐嘈的NodeJS的异常处理 许多人都有这样一种映像,NodeJS比较快: 但是因为其是单线程,所以它不稳定,有点不安全,不适合处理复杂业务: 它比较适合对并发要求比较高,而且简单的业务场景. 在E ...
- 深入理解 Node.js 进程与线程
原文链接: https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651557398&idx=1&sn=1fb991da ...
- 避免uncaughtException错误引起node.js进程崩溃
uncaughtException 未捕获的异常, 当node.js 遇到这个错误,整个进程直接崩溃. 或许这俩个人上辈子一定是一对冤家. 或许这俩个人经历了前世500次的回眸才换来了今生的相遇,只可 ...
- Node.js进程管理之子进程
一.理论 之前看多进程这一章节时发现这块东西挺多,写Process模块的时候也有提到,今天下午午休醒来静下心来好好的看了一遍,发现也不是太难理解. Node.js是单线程的,对于现在普遍是多处理器的机 ...
- Node.js进程管理之Process模块
在前面Node.js事件运行机制也有提到,Node.js应用在单个线程运行,但是现在大部分服务器都是多处理器,为了方便使用多个进程,Node.js提供了3个模块.Process模块提供了访问正在运行的 ...
- 一起来学node.js吧 node school简介
node.js这几年火爆的简直丧心病狂,去lagou.com查查node.js的职位,那叫一个多. 要说火爆到什么程度,竟然有一个网站专门去教大家学习node.js, Node School. 进去逛 ...
- .NET程序员也学Node.js——初识Node.js
清明在石门休了八天假,一眨眼,4月又到中旬了...看到.NET在天朝彻底沦陷而又无能为力,我开始尝试去学习一些新的东西来充实自己,我自然是打死不会去学java的,没有为什么,于是乎,最近开始学习一些前 ...
- Process Node.js 进程
Process 进程 process.argv 是命令行参数数组,第一个元素是node,第二个元素是脚本文件名,从第三个元素开始每个元素是一个运行参数. process.stdout 标准输出流 co ...
- Node.js 进程
process 是全局对象,能够在任意位置访问,是 EventEmitter 的实例. 退出状态码 当没有新的异步的操作等待处理时,Node 正常情况下退出时会返回状态码 0 .下面的状态码表示其他状 ...
随机推荐
- 使用Html5+C#+微信 开发移动端游戏详细教程 总目录
(一).序(关于作者创业失败的感想) (二).准备工作&开发环境 (三).使用html5引擎搭建游戏框架 (四).游戏中层的概念与设计 (五).游戏图像的加载与操作 (六).游戏界面布局与性能 ...
- 每天2分钟平板支撑Plank,锻炼核心肌群,远离背疼痛
本文已转至 http://www.zhoujingen.cn/blog/2692.html 平板支撑(plank)被公认为训练核心肌群最有效的方法之一,每天坚持做可以让平坦的小腹重见天日.据说目前p ...
- Android 学习笔记之AndBase框架学习(三) 使用封装好的函数完成Http请求..
PS:踏踏实实走好每一步... 学习内容: 1.使用AndBase框架实现无参Http Get请求... 2.使用AndBase框架实现有参Http Post请求... 3.使用AndBase框架实现 ...
- ASP.NET 让无码编程不在是梦 -.NET通用平台、通用权限、易扩展、多语言、多平台架构框架
先拿出我半前年前平台的设计初稿,经过半年的努力我已经完成了该设计稿的所有功能.并且理念已经远远超出该设计稿. 下面是一些博友对我贴子的评价: 1.楼主,想法很美好,现实很骨感,我们公司就有一套你说的这 ...
- CSS3魔法堂:禁止用户改变textarea大小
一.前言 在FF.Chrome和Safari下默认时允许用户以拖拽形式来改变textarea大小,这不仅与IE下textarea的行为特点有异,而且textarea的大小变化会撑大其父节点从而破坏整体 ...
- ok6410 android driver(10)
From this essay, we go to a new discussion "Android Hardware Abstraction Layer". In this e ...
- ASP.NET MVC的路由
好久没写博文了,感觉最近好像少了点动力.唉!这回就看看这个MVC的路由. 说这个路由机制其实不是MVC里面特有的,ASP.NET里面本身就有的,只不过在WebForm里面一般比较少用,而在MVC里就是 ...
- 安装win8、ubuntu双系统的过程
弄了一个晚上,终于完成了,之前是用虚拟机的,但是觉得不带劲,并且折腾来时菜鸟变大神的捷径,虽然现在还一直在爬坑.继续奋斗吧...王小二 首先是看 ubuntu 百度贴吧的安装帖子(http://tie ...
- sql server2008中左连接,右连接,等值连接的区别
数据库中的连接我了解到有left join,right join,inner join这些,以下是它们的区别: 1)左连接(left join):先取出a表的所有数据,再取出a.b表相匹配的数据 2) ...
- IIS理解
WEB开发基础 1IIS原理 IIS的本质其实就是一个sorket的服务器,浏览器就是一个sorket的客户端,浏览器发送请求信息给IIS,IIS返回信息给浏览器显示,就这么简单. 1http.sys ...