Node.js 是如何工作的?
Node.js 的主要思路是:使用非阻塞的,事件驅動的 I/O 操作來保持在處理跨平臺 (across distributed devices) 資料密集型實時應用時的輕巧高效。這聽起來有點繞口。
它的真正含義是,Node.js 不是一個即將主導Web開發的世界的銀彈級的平臺。相反,它是一個滿足特別需求的平臺。你肯定不會希望使用 Node.js 去做 CPU密集型操作。事實上,使用它進行繁重的計算等於摒棄 Node 幾乎所有的優點。Node 真正的亮點在於建設高效能,高擴充套件性的網際網路應用——因為它能夠處理龐大的並且高吞吐量的併發連線。
它的工作原理是相當有趣的。傳統的網路服務技術,是每個新增一個連線(請求)便生成一個新的執行緒,這個新的執行緒會佔用系統記憶體,最終會佔掉所有的可用記憶體。而 Node.js 僅僅只執行在一個單執行緒中,使用非阻塞的非同步 I/O 呼叫,所有連線都由該執行緒處理,在 libuv 的加分下,可以允許其支援數萬併發連線(全部掛在該執行緒的事件迴圈中)。
做一個簡單的計算: 假設是普通的Web程式,新接入一個連線會佔用 2M 的記憶體,在有 8GB RAM的系統上執行時, 算上執行緒之間上下文切換的成本,併發連線的最大理論值則為 4000 個。這是在傳統 Web服務端技術下的處理情況。而 Node.js 則達到了約 1M 一個併發連線的拓展級別 (相關證明).
當然,在所有客戶端的請求共享單一執行緒時也會有問題, 這也是一個編寫 Node.js 應用的潛在缺陷. 首先, 大量的計算可能會使得 Node 的單執行緒暫時失去反應, 並導致所有的其他客戶端的請求一直阻塞, 直到計算結束才恢復正常。 其次,開發人員需要非常小心,不要讓一個 Exception 阻塞核心的事件迴圈,因為這將導致 Node.js 例項的終止(實際上就是程式崩潰)。( 筆者注:如 PHP 中某個頁面掛掉是不會影響網站執行的,但是 Nodejs 是一個執行緒一個執行緒來處理所有的連結,所以不論是計算卡了或者是被異常阻塞了都可能會影響到其他所有的連結。解決方案在稍後討論。)
Node.js 是如何工作的?
Node.js 的主要思路是:使用非阻塞的,事件驅動的 I/O 操作來保持在處理跨平臺 (across distributed devices) 資料密集型實時應用時的輕巧高效。這聽起來有點繞口。
它的真正含義是,Node.js 不是一個即將主導Web開發的世界的銀彈級的平臺。相反,它是一個滿足特別需求的平臺。你肯定不會希望使用 Node.js 去做 CPU密集型操作。事實上,使用它進行繁重的計算等於摒棄 Node 幾乎所有的優點。Node 真正的亮點在於建設高效能,高擴充套件性的網際網路應用——因為它能夠處理龐大的並且高吞吐量的併發連線。
它的工作原理是相當有趣的。傳統的網路服務技術,是每個新增一個連線(請求)便生成一個新的執行緒,這個新的執行緒會佔用系統記憶體,最終會佔掉所有的可用記憶體。而 Node.js 僅僅只執行在一個單執行緒中,使用非阻塞的非同步 I/O 呼叫,所有連線都由該執行緒處理,在 libuv 的加分下,可以允許其支援數萬併發連線(全部掛在該執行緒的事件迴圈中)。
做一個簡單的計算: 假設是普通的Web程式,新接入一個連線會佔用 2M 的記憶體,在有 8GB RAM的系統上執行時, 算上執行緒之間上下文切換的成本,併發連線的最大理論值則為 4000 個。這是在傳統 Web服務端技術下的處理情況。而 Node.js 則達到了約 1M 一個併發連線的拓展級別 (相關證明).
當然,在所有客戶端的請求共享單一執行緒時也會有問題, 這也是一個編寫 Node.js 應用的潛在缺陷. 首先, 大量的計算可能會使得 Node 的單執行緒暫時失去反應, 並導致所有的其他客戶端的請求一直阻塞, 直到計算結束才恢復正常。 其次,開發人員需要非常小心,不要讓一個 Exception 阻塞核心的事件迴圈,因為這將導致 Node.js 例項的終止(實際上就是程式崩潰)。( 筆者注:如 PHP 中某個頁面掛掉是不會影響網站執行的,但是 Nodejs 是一個執行緒一個執行緒來處理所有的連結,所以不論是計算卡了或者是被異常阻塞了都可能會影響到其他所有的連結。解決方案在稍後討論。)