【深入Node探究】(1)“Node特點與應用場景” 有四問
1、為什么叫Node?
它自身非常簡單,通過通信協議來組織很多Node,非常容易通過擴展來達成構建大型網絡應用的目的。每一個Node進程都構成這個網絡應用中的一個節點,這是它名字所含意義的真諦。
2、你能說說Node的特點嗎?
作為后端JavaScript的運行平臺,Node保留了前端瀏覽器JavaScript中那些熟悉的接口,沒有改寫語言本身的任何特性,依舊基于作用域和原型鏈,區別在于它將前端中廣泛運用的思想遷移到了服務器端。下面我們可以看看node相較于其他語言的一些特點:
(1)異步I/O
關于異步I/O,向前端工程師解釋起來或許會容易一些,因為發起Ajax調用對于前端工程師而言是再熟悉不過的場景了。下面的代碼用于發起一個Ajax請求:
- $.post('/url', {title: ’深入淺出Node.js'}, function (data) {
- console.log(’收到響應’);
- });
- console.log(’發送Ajax結束’);
熟悉異步的用戶必然知道,“收到響應”是在“發送Ajax結束”之后輸出的。在調用$.post()后,后續代碼是被立即執行的,而“收到響應”的執行時間是不被預期的。我們只知道它將在這個異步請求結束后執行,但并不知道具體的時間點。異步調用中對于結果值的捕獲是符合“Don't call me, I will call you”的原則的,這也是注重結果,不關心過程的一種表現。
(2)事件與回調函數
Node不像Rhino那樣受Java的影響很大,而是將前端瀏覽器中應用廣泛且成熟的事件引入后端,配合異步I/O,將事件點暴露給業務邏輯。
相比之下,無論在前端還是后端,事件都是常用的。對于其他語言來說,這種俯拾皆是JavaScript的熟悉感覺是基本不會出現的。
(3)單線程
Node保持了JavaScript在瀏覽器中單線程的特點。而且在Node中,JavaScript與其余線程是無法共享任何狀態的。
單線程的最大好處是不用像多線程編程那樣處處在意狀態的同步問題,這里沒有死鎖的存在,也沒有線程上下文交換所帶來的性能上的開銷。
同樣,單線程也有它自身的弱點,這些弱點是學習Node的過程中必須要面對的。積極面對這些弱點,可以享受到Node帶來的好處,也能避免潛在的問題,使其得以高效利用。單線程的弱點具體有以下3方面。
- ❑ 無法利用多核CPU。
- ❑ 錯誤會引起整個應用退出,應用的健壯性值得考驗。
- ❑ 大量計算占用CPU導致無法繼續調用異步I/O。
像瀏覽器中JavaScript與UI共用一個線程一樣,JavaScript長時間執行會導致UI的渲染和響應被中斷。在Node中,長時間的CPU占用也會導致后續的異步I/O發不出調用,已完成的異步I/O的回調函數也會得不到及時執行。
3、上面提到單線程不利于計算,無法利用多核cpu,難道沒有解決方法嗎?
有的。
Node采用了與Web Workers相同的思路來解決單線程中大計算量的問題:child_process。
子進程的出現,意味著Node可以從容地應對單線程在健壯性和無法利用多核CPU方面的問題。通過將計算分發到各個子進程,可以將大量計算分解掉,然后再通過進程之間的事件消息來傳遞結果,這可以很好地保持應用模型的簡單和低依賴。
4、那你可以談談node的使用場景嗎?
關于Node,探討得較多的主要有I/O密集型和CPU密集型。
I/O密集型
在Node的推廣過程中,無數次有人問起Node的應用場景是什么。如果將所有的腳本語言拿到一處來評判,那么從單線程的角度來說,Node處理I/O的能力是值得豎起拇指稱贊的。通常,說Node擅長I/O密集型的應用場景基本上是沒人反對的。Node面向網絡且擅長并行I/O,能夠有效地組織起更多的硬件資源,從而提供更多好的服務。
I/O密集的優勢主要在于Node利用事件循環的處理能力,而不是啟動每一個線程為每一個請求服務,資源占用極少。
CPU密集型
換一個角度,在CPU密集的應用場景中,Node是否能勝任呢?實際上,V8的執行效率是十分高的。單以執行效率來做評判,V8的執行效率是毋庸置疑的。
CPU密集型應用給Node帶來的挑戰主要是:由于JavaScript單線程的原因,如果有長時間運行的計算(比如大循環),將會導致CPU時間片不能釋放,使得后續I/O無法發起。但是適當調整和分解大型運算任務為多個小任務,使得運算能夠適時釋放,不阻塞I/O調用的發起,這樣既可同時享受到并行異步I/O的好處,又能充分利用CPU。
CPU密集不可怕,如何合理調度是訣竅。
最后
這是我策劃撰寫的關于深入探討node的系列文章