Node保持了JavaScript在瀏覽器中單線程的特點。而且在Node中,JavaScript與其余線程是無法共享任何狀態的。單線程的最大好處是不用像多線程編程那樣處處在意狀態同步的問題,這里沒有死鎖的存在,也沒有線程上下文交換所帶來的性能上的開銷。
同樣,單線程也有它的弱點,這些弱點是學習Node過程中必須要面對的。積極面對這點,可以享受到Node帶來的好處,也能避免潛在問題,使其得以高效利用。單線程的弱點具體有一下3個方面:
* 無法利用多核CPU。
* 錯誤會引起整個應用退出,應用的健壯性值得考研。
* 大量計算占用CPU導致無法繼續調用異步I/O。
像瀏覽器中JavaScript與UI共用一個線程一樣,JavaScript長時間執行會導致UI的渲染和響應被中斷。在Node中,長時間的CPU占用也會導致后續的異步I/O發不出調用,已完成的異步I/O的回調函數也會得不到及時執行。
最早解決這種大計算量問題的方案是Google公司開發的Gears。它啟用一個完全獨立的進程,將需要計算的程序發送給這個進程,在結果得出后,通過事件將結果傳遞回來。這個模型將計算量分發到其它進程上,以此來降低運算造成阻塞的幾率。后來,HTML5定制了Web Workers的標準,Google放棄了Gears,全力支持Web Workers。Web Workers能夠創建工作線程來進行計算,以解決JavaScript大計算阻塞UI渲染的問題。工作線程為了不阻塞主線程,通過消息傳遞的方式來傳遞運行結果,這也使得工作線程不能訪問到主線程中的UI。
Node采用了與Web Workers相同的思路來解決單線程中大計算量的問題:child_process 。
子進程的出現,意味著Node可以從容的應對單線程在健壯性和無法利用多核CPU方面的問題。通過將計算分發到各個子進程,可以將大量計算分解掉,然后再通過進程之間的事件消息來傳遞結果,這可以很好的保持應用模型的簡單和低依賴。通過Master-Worker的管理方式,也可以很好的管理各個工作進程,以達到更高的健壯性。
關于如何通過子進程來充分利用硬件資源和提升應用健壯性,這是一個值得探究的話題。怎樣才能使我們既享受到無憂無慮的單線程編程,又高效利用資源呢?請挪步到第9章。
- 目錄
- 第1章 Node 簡介
- 1.1 Node 的誕生歷程
- 1.2 Node 的命名與起源
- 1.2.1 為什么是 JavaScript
- 1.2.2 為什么叫 Node
- 1.3 Node給JavaScript帶來的意義
- 1.4 Node 的特點
- 1.4.1 異步 I/O
- 1.4.2 事件與回調函數
- 1.4.3 單線程
- 1.4.4 跨平臺
- 1.5 Node 的應用場景
- 1.5.1 I/O 密集型
- 1.5.2 是否不擅長CPU密集型業務
- 1.5.3 與遺留系統和平共處
- 1.5.4 分布式應用
- 1.6 Node 的使用者
- 1.7 參考資源
- 第2章 模塊機制
- 2.1 CommonJS 規范
- 2.1.1 CommonJS 的出發點
- 2.1.2 CommonJS 的模塊規范
- 2.2 Node 的模塊實現
- 2.2.1 優先從緩存加載
- 2.2.2 路徑分析和文件定位
- 2.2.3 模塊編譯
- 2.3 核心模塊
- 2.3.1 JavaScript核心模塊的編譯過程
- 2.3.2 C/C++核心模塊的編譯過程
- 2.3.3 核心模塊的引入流程
- 2.3.4 編寫核心模塊
- 2.4 C/C++擴展模塊
- 2.4.1 前提條件
- 2.4.2 C/C++擴展模塊的編寫
- 2.4.3 C/C++擴展模塊的編譯
- 2.4.2 C/C++擴展模塊的加載
- 2.5 模塊調用棧
- 2.6 包與NPM
- 2.6.1 包結構
- 2.6.2 包描述文件與NPM
- 2.6.3 NPM常用功能
- 2.6.4 局域NPM
- 2.6.5 NPM潛在問題
- 2.7 前后端共用模塊
- 2.7.1 模塊的側重點
- 2.7.2 AMD規范
- 2.7.3 CMD規范
- 2.7.4 兼容多種模塊規范
- 2.8 總結
- 2.9 參考資源
- 第3章 異步I/O
- 3.1 為什么要異步I/O
- 3.1.1 用戶體驗
- 3.1.2 資源分配
- 3.2 異步I/O實現現狀
- 3.2.1 異步I/O與非阻塞I/O
- 3.2.2 理想的非阻塞異步I/O
- 3.2.3 現實的異步I/O
- 3.3 Node的異步I/O
- 3.3.1 事件循環
- 3.3.2 觀察者
- 3.3.3 請求對象
- 3.3.4 執行回調
- 3.3.5 小結
- 3.4 非I/O的異步API
- 3.4.1 定時器
- 3.5 事件驅動與高性能服務器