對 Node.js 事件驅動模型的深入理解

PHP定製開發發表於2022-09-23

本文主要討論以下問題:

1.Node.js 的事件驅動模型分析

2.Node.js 如何處理高併發請求?

3.Node.js 的缺點介紹

先簡單介紹一下 Node.js,Node.js 是基於事件驅動、非阻塞 I/O 模型的伺服器端 JavaScript 執行環境,是基於 Google 的 V8 引擎在伺服器端執行的單執行緒、高效能的 JavaScript 語言。

一、 Node.js 事件驅動模型分析

對 Node.js 事件驅動模型的深入理解
 

看懂上圖之後,你就明白 Node.js 的事件驅動模型了,從上圖中我們可以看到以下幾個部分:

Application 應用層,也就是 JavaScript 互動層,是 Node.js 的常用模組,比如 http,fs 等。

V8 是 V8 引擎層,主要用於解析 JavaScript,與應用層和 NodeApi 層互動。

NodeApi 為上層模組提供系統呼叫,並與作業系統互動。

Libuv 是一個跨平臺的底層包,實現了執行緒池、事件迴圈、檔案操作等。實現非同步是 Node.js 的核心。

Libuv 層維護一個事件佇列的事件佇列。當請求到來時,Node.js 的應用層和 NodeApi 層將請求作為事件放入事件佇列,設定回撥事件函式,然後繼續接受新的請求。

在 Libuv 層的 Event Loop 事件迴圈中,事件佇列中的事件被連續讀取。在讀取事件的過程中,如果遇到非阻塞事件,就自己處理,處理完後呼叫回撥函式將結果返回給下一層。對於阻塞事件,會委託給後臺執行緒池來處理。當這些阻塞操作完成後,執行結果將和提供的回撥函式一起放入事件佇列。當事件迴圈再次讀取該事件時,將再次執行放置在佇列中的事件回撥函式,最後將結果返回給上級。詳情請參考下圖:

 

對 Node.js 事件驅動模型的深入理解
 

二、 Node.js 如何處理高併發請求?

如果你理解了最後一個問題,就好理解了。如果要總結的話,就是非同步無阻塞程式設計的思想。當遇到耗時的操作時,會以非同步非阻塞的方式進入事件佇列,不會影響後續請求的執行。迴圈將讀取這個耗時的請求,並將其交給執行緒池進行處理。當這些耗時的操作被處理後,會再次進入事件佇列,請求結果透過事件迴圈和回撥返回給上層應用,最終返回給客戶端。以上方式減少了高併發的等待時間,讓高併發可以從容應對。

三、 Node.js 的缺點介紹

透過上面的介紹,我們知道了 Node.js 的事件驅動模型,下面我們將介紹 Node.js 的不足之處。

Node.js 最大的缺點是一次只能服務一個請求。目前大部分伺服器都是多核 CPU,導致 CPU 利用率非常低,資源浪費。

Node.js 的主執行緒 Event Loop 按照事件佇列的順序執行事件佇列中的事件。在其中一個任務完成之前,回撥和監聽器等其他函式都沒有機會執行,因為被阻塞的事件迴圈沒有機會處理它們。如果發生這種情況,程式執行速度將會變慢。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70021881/viewspace-2915964/,如需轉載,請註明出處,否則將追究法律責任。

相關文章