初識(shí) Node.js

簡(jiǎn)介

Node.js 專注于實(shí)現(xiàn) web 高性能的服務(wù)器,是一個(gè)讓 JavaScript 運(yùn)行在服務(wù)器上的平臺(tái)。他使用 Chrome 瀏覽器的 V8 引擎作為 JS 代碼的解釋工具,底層使用 C++ 進(jìn)行開發(fā),而 V8 引擎也正是基于 C++ 開發(fā)的。

Node.js 并不是一種新的語言,他是基于 JavaScript 實(shí)現(xiàn)的,但是他讓 JavaScript 煥發(fā)出了新的活力,將 JavaScript 的觸角伸到了服務(wù)器端。

Node.js 和傳統(tǒng)的服務(wù)器端程序的最大區(qū)別在于 Node.js 沒有 Web 容器的概念。一般來服務(wù)器程序比如 PHP、JSP、Python、Perl、Ruby 等都需要運(yùn)行在 Web 容器中才能被訪問,最常用的 Web 容器比如說 Apache、Nginx 等。但是 Node.js 沒有!通過對(duì)于頂層路由的設(shè)計(jì)能夠制定出很簡(jiǎn)潔清晰的 URL。

特點(diǎn)一:?jiǎn)尉€程

Node.js 的另一大特點(diǎn)在于他是單線程的,整個(gè) Node.js 程序運(yùn)行在單一的一個(gè)線程上。

一個(gè) Java Web 項(xiàng)目,用戶發(fā)起請(qǐng)求會(huì)為其創(chuàng)建一個(gè)線程,而每一線程都需要占用一定的內(nèi)存,所有對(duì)于服務(wù)器的要求會(huì)隨著用戶數(shù)的增加而增加,硬件成本也相應(yīng)提高。同時(shí)使用多線程會(huì)存在上下文切換和線程銷毀的開銷,如果使用單線程就能避免這些應(yīng)為多線程帶來的系統(tǒng)開銷,提高系統(tǒng)運(yùn)行效率。

Node.js 不會(huì)為每個(gè)用戶創(chuàng)建一個(gè)新的線程,而是使用同一個(gè)線程接收所有的請(qǐng)求。使用一個(gè)線程在面對(duì)多個(gè)用戶請(qǐng)求時(shí),Node 不能像多線程那樣并行地對(duì)其進(jìn)行處理。在單線程上我們順次執(zhí)行程序,在一個(gè)請(qǐng)求沒有執(zhí)行完的時(shí)候,線程就會(huì)阻塞,下一個(gè)請(qǐng)求就無法進(jìn)行。

特點(diǎn)二:非阻塞式 IO

為了應(yīng)付單線程的阻塞問題,Node 使用了非阻塞 I/O 機(jī)制。

處理一個(gè)請(qǐng)求時(shí)最耗時(shí)的操作是各種 I/O 操作,最頻繁的就是對(duì)數(shù)據(jù)庫的讀寫操作,或者是對(duì)文件的讀寫操作。在單線程中如果執(zhí)行到 I/O 操作,則線程會(huì)在此阻塞等待返回結(jié)果。

Node 為了應(yīng)付費(fèi)時(shí)的 I/O 操作使用了非阻塞 I/O 模式。當(dāng)程序一旦執(zhí)行到了 I/O 操作的部分,則立即將 I/O 操作交給回調(diào)函數(shù),自己則繼續(xù)執(zhí)行后面的程序。

這里就有兩點(diǎn)需要注意的。

一是執(zhí)行回調(diào)函數(shù)之后的代碼不能依賴回調(diào)函數(shù)的結(jié)果。比如用戶登錄的操作,需要查詢數(shù)據(jù)庫驗(yàn)進(jìn)行校驗(yàn),之后的登錄操作需要依賴回調(diào)的結(jié)果,此時(shí)必須等待返回校驗(yàn)結(jié)果才能進(jìn)行登錄操作。

二是執(zhí)行回調(diào)函數(shù)之后何時(shí)再繼續(xù)執(zhí)行。所以必須要有事件循環(huán),回過頭來繼續(xù)執(zhí)行操作,就需要不斷檢查線程上有沒有沒有處理完的事件,排隊(duì)實(shí)現(xiàn)他們。

因此 Node 的這條線程一直處于運(yùn)行狀態(tài)不會(huì)阻塞,CPU 的利用率一直很高。

特點(diǎn)三:事件驅(qū)動(dòng)

Node 的第三個(gè)特點(diǎn)就是事件驅(qū)動(dòng)。也就是前面講的在線程執(zhí)行 A 操作的過程中采用回調(diào)函數(shù)的形式轉(zhuǎn)而處理 B 事件,在 B 事件處理完之后再去執(zhí)行 B,如網(wǎng)上一張圖片所示:

事件驅(qū)動(dòng)

事件在循環(huán)執(zhí)行之中,當(dāng)遇到 I/O 操作則采用回調(diào)函數(shù)處理,處理完的事件則會(huì)排隊(duì)等候再次執(zhí)行,形成了一個(gè)個(gè)的事件環(huán)。

Node 通過非阻塞 I/O 的機(jī)制和事件驅(qū)動(dòng)的方式讓單線程的程序?qū)崿F(xiàn)了多線程的效果。讓一個(gè)線程永遠(yuǎn)處于忙碌的狀態(tài),不會(huì)造成資源的浪費(fèi)。這樣就能降低硬件的成本卻不會(huì)影響程序執(zhí)行的效率。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容