如何解决NodeJS服务总是崩溃

本篇文章给大家介绍一下如何解决nodejs服务总是崩溃。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

如何解决NodeJS服务总是崩溃

许多人都有这样一种映像,NodeJS比较快; 但是因为其是单线程,所以它不稳定,有点不安全,不适合处理复杂业务; 它比较适合对并发要求比较高,而且简单的业务场景。

事实上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');});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-errorServer running at http://127.0.0.1:8080/c:githubscriptode-error.js:5  var ok = req.params.ok;                     ^TypeError: Cannot read property 'ok' of undefined    at Server. (c:githubscriptode-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('', e, '', 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,如下图所示: 

如何解决NodeJS服务总是崩溃 

这 些Middleware和Handler在NodeJS中都有一个特点,他们都是回调函数,而回调函数中是唯一会让Node在运行时崩溃的地方。根据这个 特点,我们只需要在框架中集成一处try/catch就可以相对完美地解决异常问题,而且不会影响其它用户的请求request。 

事实上现在的NodeJS WEB框架几乎都是这么做的,如 OurJS开源博客所基于的 WebSvr 

就有这么一处异常处理代码: 

Line: 207  try {    handler(req, res);  } catch(err) {    var errorMsg      = ''      + 'Error ' + new Date().toISOString() + ' ' + req.url      + ''      + err.stack || err.message || 'unknow error'      + ''      ;    console.error(errorMsg);    Settings.showError      ? res.end('
' + errorMsg + '

登录后复制')      : 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来守护node

node-forever 提供了守护的功能和LOG日志记录功能。 

安装非常容易 

[sudo] 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

登录后复制

使用shell启动脚本守护node

使用node来守护的话资源开销可能会有点大,而且也会略显复杂,OurJS直接在开机启动脚本来进程线程守护。 

如在debian中放置的 ourjs 开机启动文件: /etc/init.d/ourjs 

这个文件非常简单,只有启动的选项,守护的核心功能是由一个无限循环 while true; 来实现的,为了防止过于密集的错误阻塞进程,每次错误后间隔1秒重启服务 

WEB_DIR='/var/www/ourjs'WEB_APP='svr/ourjs.js'#location of node you want to useNODE_EXE=/root/local/bin/nodewhile true; do    {        $NODE_EXE $WEB_DIR/$WEB_APP config.magazine.js        echo "Stopped unexpected, restarting "    } 2>> $WEB_DIR/error.log    sleep 1done

登录后复制

错误日志记录也非常简单,直接将此进程控制台当中的错误输出到error.log文件即可: 2>> $WEB_DIR/error.log  这一行, 2 代表 Error。

推荐学习:javascript视频教程

以上就是如何解决NodeJS服务总是崩溃的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2634454.html

(0)
上一篇 2025年3月7日 04:32:59
下一篇 2025年3月1日 02:26:42

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • javascript是什么类型语言

    javascript是一种动态类型、弱类型的语言,是一种基于对象和事件驱动并具有相对安全性并广泛用于客户端网页开发的脚本语言,同时也是一种广泛用于客户端Web开发的脚本语言。 本教程操作环境:windows7系统、javascript1.8…

    2025年3月7日
    200
  • javascript作用有哪些

    javascript作用有:1、嵌入动态文本于HTML页面;2、对浏览器事件做出响应;3、读写HTML元素;4、在数据被提交到服务器之前验证数据;5、检测访客的浏览器信息;6、基于Node.js技术进行服务器端编程。 本文操作环境:wind…

    2025年3月7日
    200
  • javascript是什么端

    javascript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言,也是一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态功能,比如响应用户的各种操作。 本文操作环境:windows7系统、javascript1…

    2025年3月7日
    200
  • js和javascript有区别吗

    js和javascript之间没有区别,js是javascript的缩写;它是一种高级的、解释型的编程语言。js是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。 本…

    2025年3月7日
    200
  • javascript简称什么

    javascript简称“JS”, 是一种具有函数优先的轻量级、解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果,但也可基于Node.js技术进行服务器端编程。…

    2025年3月7日
    200
  • JavaScript自我管理是什么

    JavaScript自我管理是指Grunt任务自动管理工具,Grunt可以帮助我们自动管理和运行各种任务;Grunt是一个自动任务运行器,会按照预先设定的顺序自动运行一系列的任务,这可以简化工作流程,减轻重复性工作带来的负担。 本文操作环境…

    2025年3月7日
    200
  • JavaScript是网络协议吗

    JavaScript不是网络协议,而是一种解释性脚本语言。Javascript是一种原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言遗留的速度问题,为客户提供更流畅的浏览效果。 本教程操作环境:wi…

    2025年3月7日
    200
  • 不能编辑javascript的程序有什么

    不能编辑javascript的程序有“Cool Edit Pro”,“Cool Edit Pro”是数字音乐编辑器和MP3制作软件;编辑javascript的软件有sublime text、HBuilder、dreamweaver等。 本文…

    2025年3月7日
    200
  • 浅谈动态导入ECMAScript模块的方法

    ECMAScript(又名ES2015或ES)模块是在JavaScript中组织内聚代码块的一种方法。 ES模块系统有2个部分: import模块 – 使用 import { func } from ‘./myMod…

    2025年3月7日
    200
  • jscript和javascript的区别是什么

    区别:JScript是由微软公司开发的活动脚本语言;而JavaScript是由Netscape公司开发的解释型脚本语言。javascript是面向所有浏览器的,Jscript只是面向微软的IE浏览器。 本教程操作环境:windows7系统、…

    2025年3月7日
    200

发表回复

登录后才能评论