设为首页 收藏本站
查看: 981|回复: 0

[经验分享] NodeJS异常处理uncaughtException篇

[复制链接]

尚未签到

发表于 2017-2-22 12:29:48 | 显示全部楼层 |阅读模式
  很多 NodeJS 的开发者在抱怨异常处理太麻烦,我们会通过一些列博客梳理一下NodeJS中常见的异常处理的手段。
  
和大多数编程语言一样,在 NodeJS 里可以通过throw抛出一个异常:
  

throw new Error('Catch me');  

  为了捕获这个异常需要把代码包在Try Catch中:
  

try{  throw new Error('Catch me');
  
}catch(e){
  // error captured
  
}
  

  然而,由于 NodeJS 的异步特性,上述代码只需稍加改造就会失效:
  

try{  process.nextTick(function my_app(){
  throw new Error('Catch me');
  })
  
}catch(e){
  // never called
  
}
  

  在现实世界里,异常总是会产生在某个模块中。所谓模块就是能完成一个功能的单元,即使是一个简单的函数也可以被看做一个模块。随着项目代码行数增多,异步嵌套的复杂性加强,经常会有异常没捕获的情况发生。一个没有很强健壮性的 NodeJS 应用,会因为一个未捕获的异常就整个挂掉,导致服务不可用。要改变大家觉得NodeJS是脆弱的这个认识,需要开发者加深对这门语言异常处理机制的了解。

uncaughtException
  uncaughtException 其实是 NodeJS 进程的一个事件。如果进程里产生了一个异常而没有被任何Try Catch捕获会触发这个事件。为了简化问题,我们还是先看看同步情况下的例子。
  

function external() {  throw new Error('Catch me');
  
}
  

  
function internal() {
  external();
  
}
  

  
internal(); //error will be thrown
  

  在命令行里执行这个程序,脚本会在抛出异常的那一行中断。接下来,由于没有Try Catch,异常会一直冒泡直到事件循环为止,而NodeJS对异常的默认处理非常简单,处理的代码 类似 于:
  

function _MyFatalException(err){  if(!process.emit('uncaughtException',err)){
  console.error(err.stack);
  process.emit('exit',1);
  }
  
}
  

  NodeJS对于未捕获异常的默认处理是: - 触发 uncaughtException 事件 - 如果 uncaughtException 没有被监听,那么 - 打印异常的堆栈信息 - 触发进程的 exit 事件
  如果你正在用 NodeJS 开发服务器,那么你肯定不希望偶然的一个异常让整个服务器挂掉。那么是不是只要监听了 uncaughtException 就可以阻止服务器的进程退出呢? 答案是可以,但是不要这么做!。看这个例子:
  

var express = require('express');  

  
function external(cb) {
  process.nextTick(function () {
  throw new Error();
  cb.call(null, 'sunny');
  })
  
}
  

  
var app = express();
  
app.get('/weather', function (req, res) {
  external(function (data) {
  res.end('Weather of Beijing is ' + data);
  })
  
})
  
app.listen(8018);
  

  

  
function noop(){}
  
process.on('uncaughtException', noop)
  

  上面这个例子假设用户访问站点的时候可以看到当地的天气,我们用 apache2-utils 来模拟请求

  ab -n 1000 -c 20 http://localhost:8018/weather

  糟糕!请求一直在等待,内存上涨。原因在于res.end 永远不会执行,现有的I/O处于等待的状态,已经开辟的资源不仅不会被释放,而且服务器还在不知疲倦地接受新的用户请求。
  在 NodeJS 中处理异常是代价高昂的,而且一不小心就会导致内存泄露和让应用程序处于不稳定的状态。为了提高健壮性,我们可以用Cluster模式,由之而来的推荐做法是: - 针对发生异常的请求返回一个错误代码 - 出错的Worker不再接受新的请求 - 退出关闭Worker进程
  
***
  本文系iyunv工程师编译整理。iyunv是中国基础软件领域的新兴领军企业,能帮助企业用户和开发者轻松实现:缓慢的程序代码和SQL语句的实时抓取。想阅读更多技术文章,请访问iyunv官方技术博客。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-345768-1-1.html 上篇帖子: NodeJS入门(五)—— process对象 下篇帖子: MemCache在win7上的可视化配置以及Nodejs/Net应用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表