因为我们的产品主要是以js栈为主,下面来讲一下我们实践。
e.stack 异常栈
node.js是出错异常了,最关键是要知道哪错了。stack是error很重要的一个属性,可以帮助我们了解代码到底是执行哪一行出错了,比如某个error 的 stack:
Error: "start" option must be <= "end" option at new ReadStream (fs.js:1931:13) at Object.fs.createReadStream (fs.js:1885:10) at /var/www/oncedoc/mod/onceoa-oncedoc/svr/onceoa.web.js:1:2315 at FSReqWrap.oncomplete (fs.js:123:15)
Node.JS异常处理
node.js 因欺回调的特性,一般采取错误前置的写法(Error First),即回调中第一个参数就为错误信息。在这个时侯可以直接将错误输出到 stderr 的命令行日志中,方便从日志中分析。
var getFolderTree = function(folderPath, tree, cb) { fs.readdir(folderPath, function(err, files) { if (err) { console.error(err) cb && cb(err, tree) return }
Node.JS未知异常捕获
因为是动态脚本语言,但有时也会漏掉异常捕获,这几乎是无法避免的,这时就可以在uncaughtException 中借助 e.stack 打印调出用栈。将未捕获的异常其找出来。
process.on('uncaughtException', function (err) { /* console.error may not exist in some version of node https://github.com/nodejs/node/issues/4467 */ if (typeof console.error === "function") { console.error((err || '').toString()) console.error(err.stack || '') } else { console.log((err || '').toString()) console.log(err.stack || '') } })
将异常写入日志
这是最关键的一步,上面我们已经将所有的 error 都输出到了 stderr 中,这时侯就要从命令行写入日志文件,在linux中调用node程序时可以这样简单实现:
while true; do { /usr/local/bin/node /var/www/oncedoc/svr/oncedoc.js config.live.js echo "OnceDoc stopped, restarting \r\n\r\n" } 2>> /var/www/oncedoc/error.log sleep 1 done
2 代表是 stderr 中的错误信息,可以调成 1 或 0,此时可以输出所有日志。
将这段脚本加入自动启动服务即可。
这段代码也有一定的缺陷,会block住当前的shell脚本,在实践中,我们会以一个node.js service启动另一个service,类似 forever,即守护进程。
并且我们将所有session都放入了redis,即使发生异常,也能瞬间重启,让用户感觉不到。
然后每隔一段时间排查错误日志,即可消除node中的所有异常。
回复 (0)
微信扫码 立即评论