Node.js 的異步 IO 性能探討
Python 和 Ruby 也有這樣的框架,但因?yàn)樵趯?shí)際使用中會(huì)不可避免地用到含有同步代碼的庫(kù),因此沒(méi)能成長(zhǎng)起來(lái),而在 Node.js 之前,JavaScript 的服務(wù)器端編程幾乎是空白,所以 Node.js 才得以建立起了一個(gè)所有 IO 均為異步的代碼庫(kù)。
大部分 Web 應(yīng)用的瓶頸都在 IO, 即讀寫(xiě)磁盤(pán),讀寫(xiě)網(wǎng)絡(luò),讀寫(xiě)數(shù)據(jù)庫(kù)。使用怎樣的策略等待這段時(shí)間,就成了改善性能的關(guān)鍵點(diǎn)。
PHP 的策略:多進(jìn)程運(yùn)行,直接原地等待 IO 完成。缺點(diǎn):多個(gè)進(jìn)程會(huì)消耗多份內(nèi)存,進(jìn)程間難以共享數(shù)據(jù)。
C/C++ 通常的策略:多線程運(yùn)行,程序自己維護(hù)鎖的狀態(tài)。缺點(diǎn):開(kāi)發(fā)成本高,容易出錯(cuò),不易調(diào)試。
Python(Tornado): 多個(gè)請(qǐng)求在單個(gè)進(jìn)程中輪流執(zhí)行,遇到 IO 時(shí)切換到另一個(gè)請(qǐng)求。缺點(diǎn):對(duì)于單個(gè)請(qǐng)求而言,依然沒(méi)有最高效地利用時(shí)間。
何謂「最高效地利用時(shí)間」?比如現(xiàn)在有兩個(gè)不相關(guān)的數(shù)據(jù)庫(kù)查詢,在 PHP 中通常會(huì)先執(zhí)行一個(gè),執(zhí)行完成后再執(zhí)行第二個(gè)(總時(shí)間是 a + b). 顯然這不是最高效的,應(yīng)該同時(shí)執(zhí)行兩個(gè)查詢,時(shí)間是 max(a, b).
Python 和其他支持多線程的語(yǔ)言的問(wèn)題就在于,在語(yǔ)言層面,程序員很難告訴虛擬機(jī),應(yīng)當(dāng)將兩個(gè)操作同時(shí)執(zhí)行,即使有辦法,也相當(dāng)麻煩,大多數(shù)人懶得去用(也不值得去用)。而因?yàn)?Node.js 喪心病狂地強(qiáng)制所有 IO 異步執(zhí)行,Node.js 的程序員也可以說(shuō)是輕車熟路,配合一些改善代碼可讀性庫(kù)(promise, async), 可以很輕松地讓不相干的操作并行執(zhí)行。
上面講了異步 IO 的實(shí)現(xiàn),那么異步 IO 的優(yōu)勢(shì)究竟體現(xiàn)在哪里呢。實(shí)際上異步 IO 并不能神奇地減輕服務(wù)器的壓力,該加服務(wù)器還是一樣要加服務(wù)器,只不過(guò)異步 IO 會(huì)減少單個(gè)請(qǐng)求的時(shí)間,去掉單個(gè)請(qǐng)求中那些無(wú)意義的等待時(shí)間。所以單位時(shí)間內(nèi)處理的請(qǐng)求沒(méi)有變化,但每個(gè)請(qǐng)求的處理時(shí)間卻減少了。從這個(gè)角度,服務(wù)器也節(jié)約了一些資源——即維持每個(gè)請(qǐng)求的連接消耗的內(nèi)存。
相關(guān)文章
nodejs socket服務(wù)端和客戶端簡(jiǎn)單通信功能
這篇文章主要為大家詳細(xì)介紹了nodejs socket服務(wù)端和客戶端簡(jiǎn)單通信功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09在Node.js應(yīng)用中讀寫(xiě)Redis數(shù)據(jù)庫(kù)的簡(jiǎn)單方法
這篇文章主要介紹了在Node.js應(yīng)用中讀寫(xiě)Redis數(shù)據(jù)庫(kù)的簡(jiǎn)單方法,Redis是一個(gè)內(nèi)存式高速數(shù)據(jù)庫(kù),需要的朋友可以參考下2015-06-06Node.js發(fā)送HTTP客戶端請(qǐng)求并顯示響應(yīng)結(jié)果的方法示例
這篇文章主要介紹了Node.js發(fā)送HTTP客戶端請(qǐng)求并顯示響應(yīng)結(jié)果的方法,結(jié)合完整實(shí)例形式分析了nodejs發(fā)送http請(qǐng)求及響應(yīng)的相關(guān)操作技巧,需要的朋友可以參考下2017-04-04NodeJS Web應(yīng)用監(jiān)聽(tīng)sock文件實(shí)例
這篇文章主要介紹了NodeJS Web應(yīng)用監(jiān)聽(tīng)sock文件實(shí)例,本文講解 NodeJS 的 TCP 和 HTTP 監(jiān)聽(tīng) Domain Socket 文件例子,需要的朋友可以參考下2015-02-02Node.js版本發(fā)布策略頻率與穩(wěn)定性的平衡
這篇文章主要為大家介紹了Node.js版本發(fā)布策略頻率與穩(wěn)定性的平衡,幫助大家大家更清晰了解node發(fā)展史,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Mongoose實(shí)現(xiàn)虛擬字段查詢的方法詳解
這篇文章主要給大家介紹了關(guān)于Mongoose實(shí)現(xiàn)虛擬字段查詢的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08PostgreSQL Node.js實(shí)現(xiàn)函數(shù)計(jì)算方法示例
這篇文章主要給大家介紹了關(guān)于PostgreSQL Node.js實(shí)現(xiàn)函數(shù)計(jì)算的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02