日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

被吐嘈的NodeJS的异常处理

發(fā)布時(shí)間:2023/11/29 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 被吐嘈的NodeJS的异常处理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

被吐嘈的NodeJS的異常處理


許多人都有這樣一種映像,NodeJS比較快; 但是因?yàn)槠涫菃尉€程,所以它不穩(wěn)定,有點(diǎn)不安全,不適合處理復(fù)雜業(yè)務(wù); 它比較適合對(duì)并發(fā)要求比較高,而且簡(jiǎn)單的業(yè)務(wù)場(chǎng)景。?

在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?

其實(shí)這幾條主要吐嘈了兩點(diǎn): node.js錯(cuò)誤處理很扯蛋,node.js的回調(diào)也很扯蛋。?

事實(shí)上呢?


事實(shí)上NodeJS里程確實(shí)有“脆弱”的一面,單線程的某處產(chǎn)生了“未處理的”異常確實(shí)會(huì)導(dǎo)致整個(gè)Node.JS的崩潰退出,來(lái)看個(gè)例子, 這里有一個(gè)node-error.js的文件:?

var http = require('http');var server = http.createServer(function (req, res) { //這里有個(gè)錯(cuò)誤,params 是 undefined var ok = req.params.ok; res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }); server.listen(8080, '127.0.0.1'); console.log('Server running at http://127.0.0.1:8080/');


啟動(dòng)服務(wù),并在地址欄測(cè)試一下發(fā)現(xiàn)?http://127.0.0.1:8080/? 不出所料,node崩潰了?


$ node node-error Server running at http://127.0.0.1:8080/c:\github\script\node-error.js:5 var ok = req.params.ok; ^ 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)



怎么解決呢?


其實(shí)Node.JS發(fā)展到今天,如果連這個(gè)問(wèn)題都解決不了,那估計(jì)早就沒(méi)人用了。?

使用uncaughtException


我們可以u(píng)ncaughtException來(lái)全局捕獲未捕獲的Error,同時(shí)你還可以將此函數(shù)的調(diào)用棧打印出來(lái),捕獲之后可以有效防止node進(jìn)程退出,如:?

process.on('uncaughtException', function (err) {//打印出錯(cuò)誤console.log(err);//打印出錯(cuò)誤的調(diào)用棧方便調(diào)試 console.log(err.stack); });


這相當(dāng)于在node進(jìn)程內(nèi)部進(jìn)行守護(hù), 但這種方法很多人都是不提倡的,說(shuō)明你還不能完全掌控Node.JS的異常。?

使用 try/catch


我們還可以在回調(diào)前加try/catch,同樣確保線程的安全。?

var http = require('http');http.createServer(function(req, res) { try { handler(req, res); } catch(e) { console.log('\r\n', e, '\r\n', 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); };


這種方案的好處是,可以將錯(cuò)誤和調(diào)用棧直接輸出到當(dāng)前發(fā)生的網(wǎng)頁(yè)上。?

集成到框架中


標(biāo)準(zhǔn)的HTTP響應(yīng)處理會(huì)經(jīng)歷一系列的Middleware(HttpModule),最終到達(dá)Handler,如下圖所示:?

?


這 些Middleware和Handler在NodeJS中都有一個(gè)特點(diǎn),他們都是回調(diào)函數(shù),而回調(diào)函數(shù)中是唯一會(huì)讓Node在運(yùn)行時(shí)崩潰的地方。根據(jù)這個(gè) 特點(diǎn),我們只需要在框架中集成一處try/catch就可以相對(duì)完美地解決異常問(wèn)題,而且不會(huì)影響其它用戶的請(qǐng)求request。?

事實(shí)上現(xiàn)在的NodeJS WEB框架幾乎都是這么做的,如?OurJS開(kāi)源博客所基于的?WebSvr?

就有這么一處異常處理代碼:?

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


那么不在回調(diào)中產(chǎn)生的錯(cuò)誤怎么辦?不必?fù)?dān)心,其實(shí)這樣的node程序根本就起不起來(lái)。?

此外node自帶的?cluster?也有一定的容錯(cuò)能力,它跟nginx的worker很類似,但消耗資源(內(nèi)存)略大,編程也不是很方便,OurJS并沒(méi)有采用此種設(shè)計(jì)。?

守護(hù)NodeJS進(jìn)程和記錄錯(cuò)誤日志


現(xiàn) 在已經(jīng)基本上解決了Node.JS因異常而崩潰的問(wèn)題,不過(guò)任何平臺(tái)都不是100%可靠的,還有一些錯(cuò)誤是從Node底層拋出的,有些異常 try/catch和uncaughtException都無(wú)法捕獲。之前在運(yùn)行ourjs的時(shí)侯,會(huì)偶爾碰到底層拋出的文件流讀取異常,這就是一個(gè)底層 libuv的BUG,node.js在0.10.21中進(jìn)行了修復(fù)。?

面對(duì)這種情況,我們就應(yīng)該為nodejs應(yīng)用添加守護(hù)進(jìn)程,讓NodeJS遭遇異常崩潰以后能馬上復(fù)活。?

另外,還應(yīng)該把這些產(chǎn)生的異常記錄到日志中,并讓異常永遠(yuǎn)不再發(fā)生。?

使用node來(lái)守護(hù)node


node-forever?提供了守護(hù)的功能和LOG日志記錄功能。?

安裝非常容易?

[sudo] npm install forever


使用也很簡(jiǎn)單?

$ forever start simple-server.js $ forever list[0] simple-server.js [ 24597, 24596 ]


還可以看日志?

forever -o out.log -e err.log my-script.js

?

使用shell啟動(dòng)腳本守護(hù)node


使用node來(lái)守護(hù)的話資源開(kāi)銷(xiāo)可能會(huì)有點(diǎn)大,而且也會(huì)略顯復(fù)雜,OurJS直接在開(kāi)機(jī)啟動(dòng)腳本來(lái)進(jìn)程線程守護(hù)。?

如在debian中放置的 ourjs 開(kāi)機(jī)啟動(dòng)文件:?/etc/init.d/ourjs?

這個(gè)文件非常簡(jiǎn)單,只有啟動(dòng)的選項(xiàng),守護(hù)的核心功能是由一個(gè)無(wú)限循環(huán) while true; 來(lái)實(shí)現(xiàn)的,為了防止過(guò)于密集的錯(cuò)誤阻塞進(jìn)程,每次錯(cuò)誤后間隔1秒重啟服務(wù)?

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

?

錯(cuò)誤日志記錄也非常簡(jiǎn)單,直接將此進(jìn)程控制臺(tái)當(dāng)中的錯(cuò)誤輸出到error.log文件即可: 2>> $WEB_DIR/error.log? 這一行, 2 代表 Error。

?

轉(zhuǎn)自:?OurJS

總結(jié)

以上是生活随笔為你收集整理的被吐嘈的NodeJS的异常处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。