歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Node.js異常處理uncaughtException篇

很多 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進程

CentOS編譯安裝MongoDB http://www.linuxidc.com/Linux/2012-02/53834.htm

CentOS 編譯安裝 MongoDB與mongoDB的php擴展 http://www.linuxidc.com/Linux/2012-02/53833.htm

CentOS 6 使用 yum 安裝MongoDB及服務器端配置 http://www.linuxidc.com/Linux/2012-08/68196.htm

Ubuntu 13.04下安裝MongoDB2.4.3 http://www.linuxidc.com/Linux/2013-05/84227.htm

MongoDB入門必讀(概念與實戰並重) http://www.linuxidc.com/Linux/2013-07/87105.htm

Ubunu 14.04下MongoDB的安裝指南 http://www.linuxidc.com/Linux/2014-08/105364.htm

《MongoDB 權威指南》(MongoDB: The Definitive Guide)英文文字版[PDF] http://www.linuxidc.com/Linux/2012-07/66735.htm

Nagios監控MongoDB分片集群服務實戰 http://www.linuxidc.com/Linux/2014-10/107826.htm

基於CentOS 6.5操作系統搭建MongoDB服務 http://www.linuxidc.com/Linux/2014-11/108900.htm

MongoDB 的詳細介紹:請點這裡
MongoDB 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved