提升nodejs穩定性的方法:1、保持良好的程式碼結構;2、使用「try~catch」來擷取異常;3、使用domain模組來處理程式的異常;4、使用log4js模組記錄日誌;5、使用forever模組管理nodejs。
本教學操作環境:windows7系統、nodejs 12.19.0版,DELL G3電腦。
提高nodejs程式的穩定性,健壯性
#在網路上看到一些帖子,吐糟,質疑nodejs 程式的穩定性,為什麼呢?其一,可能這個和javascript有關吧,node是拿javascript去實現的,而javascript又被稱為是“世界上誤解最深的語言”,我們可以去看看nodejs 創始人的說法,可以去看看知乎的這篇文章,為什麼node 用javascript去實現,其二,nodejs 畢竟還年輕,而且官網在部分模組也標註了此模組的目前的狀態。
這2天我抽了點時間思考了下這個問題,我覺得我們程式首先功能應該是獨立的,就是一個功能出異常了,不應該去影響另外一個正常的功能,不應該將整個程式都崩潰掉,其次,即使是程式崩潰了,我們也應該有一個讓程式自動啟動,另外,應該去記錄日誌,方便我們追蹤問題。我覺得主要可以從以下方面提高nodejs 穩定性:
1)保持良好的程式碼結構:
我們知道node是單線程,非阻塞io,默認就是異步,透過回調的方式處理後面的流程,如果嵌套的層次太多了,勢必會引起程式碼邏輯結構的混亂,也不利於維護和升級,可以採用async這個非同步流程控制模組,來理清我們的程式碼邏輯。
2)使用 process.on('uncaughtException', function(err){...}); 來處理未被捕捉的錯誤。
3)使用try~catch 來捕捉例外:
這個只能解決一部分問題,不是萬能的,在上面說到因為node是單線程,非阻塞io,預設就是異步,透過回呼的方式處理後面的流程,try~catch 是不能捕獲的callback 裡面的error的錯誤的,怎麼捕獲到callback裡面的錯誤呢? 可以採用domain模組
4)使用domain模組來處理程式的異常
先看看domain的解釋:domain是 EventEmitter類別的子類別。監聽它的error事件來處理它捕捉到的錯誤。 它提供了一種方式,即以一個單一的組的形式來處理多個不同的IO操作。如果任何一個註冊到domain的事件觸發器或回調觸發了一個‘error’事件,或者拋出一個錯誤,那麼domain物件將會被通知到。而不是直接讓這個錯誤的上下文從`process.on('uncaughtException')'處理程序中丟失掉,也不會致使程式因為這個錯誤伴隨著錯誤碼立即退出。
如何使用domain 模組呢?看一個例子:
serverDomain.run(function() { // 服务器在serverDomain的作用域内被创建 http.createServer(function(req, res) { // req和res同样在serverDomain的作用域内被创建 // 但是,我们想对于每一个请求使用一个不一样的域。 // 所以我们首先创建一个域,然后将req和res添加到这个域上。 var reqd = domain.create(); reqd.add(req); reqd.add(res); reqd.on('error', function(er) { console.error('Error', er, req.url); try { res.writeHead(500); res.end('Error occurred, sorry.'); } catch (er) { console.error('Error sending 500', er, req.url); } }); }).listen(1337); }); ```
說明:先建立一個網域(domain.create()),然後將需要監控的分發器加入到該網域上,最後給網域綁定一個錯誤事件,這樣就可以監控了。
再看一個例子:
var d = domain.create(); d.on('error', function(er) { console.error('Caught error!', er); }); d.run(function() { process.nextTick(function() { setTimeout(function() { // 模拟几个不同的异步的东西 fs.open('non-existent file', 'r', function(er, fd) { if (er) throw er; // 继续。。。 }); }, 100); }); });
說明:先建立一個域,給域綁定一個錯誤事件,然後在域的上下文提供可以運行的函數
如果對於回調呢?可以這麼使用
var d = domain.create(); function readSomeFile(filename, cb) { fs.readFile(filename, 'utf8', d.bind(function(er, data) { // if this throws, it will also be passed to the domain return cb(er, data ? JSON.parse(data) : null); })); } d.on('error', function(er) { // an error occurred somewhere. // if we throw it now, it will crash the program // with the normal line number and stack message. });
當然也可以這麼使用
var d = domain.create(); function readSomeFile(filename, cb) { fs.readFile(filename, 'utf8', d.bind(function(er, data) { // if this throws, it will also be passed to the domain return cb(er, data ? JSON.parse(data) : null); })); } d.on('error', function(er) { // an error occurred somewhere. // if we throw it now, it will crash the program // with the normal line number and stack message. });
這個函數與domain.bind(callback)幾乎一模一樣。但是,除了捕捉被拋出的錯誤外,它還會攔截作為第一參數被傳遞到這個函數的Error物件。
5)使用log4js 模組記錄日誌
log4js 是一個非常強大的日誌管理工具,在可以看看github這個專案: https://github.com /nomiddlename/log4js-node
6)使用forever 模組來管理nodejs
forever 是服務端管理nodejs 的一個模組,一個命令列工具,能夠啟動,停止app 應用。 forever完全是基於命令列操作,在forever進程管理之下,創建node的子進程,透過monitor監控node子進程的運行情況,一旦檔案更新,或者進程掛掉,forever會自動重啟node伺服器,確保應用正常運行。非常的好用.
可以關注下這個項目:https://github.com/nodejitsu/forever
但是forever 也不是萬能的,也由下面這些問題:
附上本文測試程式碼:https://github.com/yupeng528/node-error
更多node相關知識,請造訪: nodejs 教學! !
以上是如何提升nodejs的穩定性的詳細內容。更多資訊請關注PHP中文網其他相關文章!