Node出错导致运行崩溃的解决方案
一、Nodejs 简介
Nodejs 能够将客户端 JavaScript 引入服务器端,从而能够编写超快速的、能够处理成千上万的套接字连接的 Web JavaScript 服务器。
二、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
由此可以看出,在使用过程中会容易出现问题,因此不用太过惊慌,积极寻找解决方案即可。
三、出错示例
1. 业务场景
我的业务场景是:无网环境下,启动服务,在终端测试项目时,发现出现报错信息,考虑是node崩溃了导致的问题。
类似于出现这样的问题:
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)
2. 我的解决方案
首先我在ubuntu中更新了node版本,安装当前最新版本node,无效果。
接下来我按照报错信息逐条搜索解决方案,很遗憾,出现类似问题的任并不多,按照现有的解决方案进行尝试,均没有解决,有几次甚至错误越来越多。
静下心来想了下,由于18.04自带的node版本是v8.x.x,所以我尝试将node更新到更新一点的版本,经过几次尝试,我使用了nodev12.x.x版本,后面测试就好用了,解决了现有的问题。
通过查找资料发现,出现这些问题的原因是:12版本带来了许多重大升级,包括更多的V8特性,http解析速度的提升,启动速度的提升,更好的诊断报告,内置堆分析工具,ESM模块的更新等。
重大更新和特性包括: 启动更快、更合理的默认堆限制、对V8内核及LTS的更新、引入llhtp,以及诊断报告、堆转储能力、Worker Threads更新、N-API和ES6模块支持的新特性。
四、其他解决方案
1. 使用uncaughtException
uncaughtException来全局捕获未捕获的Error,同时你还可以将此函数的调用栈打印出来,捕获之后可以有效防止node进程退出。
比如:
process.on('uncaughtException', function (err) {
//打印出错误
console.log(err);
//打印出错误的调用栈方便调试
console.log(err.stack);
});
2. 使用try/catch
可以在回调前加try/catch,同样确保线程的安全。
这种方案的好处是,可以将错误和调用栈直接输出到当前发生的网页上。
3. 守护NodeJS进程和记录错误日志
3.1 使用node来守护node
node-forever 提供了守护的功能和LOG日志记录功能。
操作指令如下:
安装 : npm install forever
使用: forever start simple-server.js
forever list [0] simple-server.js [ 24597, 24596 ]
看日志 :forever -o out.log -e err.log my-script.js
3.2 使用shell启动脚本守护node
如在debian中放置的 ourjs 开机启动文件: /etc/init.d/ourjs
错误日志记录也非常简单,直接将此进程控制台当中的错误输出到error.log文件即可
以上方案在此次出现的问题上都尝试了,使用uncaughtException和使用node来守护node使用比较方便,如果大家出现问题可以尝试上面几种方法。