我與Node.js從新認識的第一週 - Node.js 風格特色

書接上回,

慢慢悠悠讀了《深刻淺出node.js》(後面簡寫做《深淺》)以及《node.js高級編程》(後面簡寫做《高級》)的開頭部分,查了很多網絡資料,關於node.js的特色有了必定了解。深究起來須要再看看操做系統以及網絡的知識。

《深淺》中提到了四個node.js的特色:異步I/O,事件與回調函數,單線程以及跨平臺。
《高級》中基本是一筆帶過,提到了純事件驅動以及非阻塞。

其中對於異步I/O以及單線程這兩個特性,我認爲能夠分如下三個方向來概述爲何node.js把天賦點在了這它們上面?前端

1. 用戶體驗

從前端加載的角度來看,比較直接。先說爲何JavaScript用異步?!咱們反着思考,若是JavaScript是同步的,會有什麼問題。請求一個用戶管理頁面,用js加載若干資源,先加載一個用戶頭像,再加載第二個,第三個。。。GG,用戶覺得卡死了,二話不說給你關了(《深淺》中提到腳本時間超過100毫秒,用戶就會有卡頓的感受;並且運行在單線程上的JavaScript還與UI渲染公用一個進程)。實際中,JavaScript的異步消除/減弱了UI阻塞的現象,同步時候加載資源的總時間是X+Y+Z,異步下的總時間則是max(X+Y+Z),可見差距。另外《深淺》中來提到目前網絡發展,分佈式應用普及,前面XYZ的數值在增加,那麼能夠想象到X+Y+Z和max(X+Y+Z)的差距確定愈來愈大。由此能夠看出異步大法好,你們都說屌!那麼node.js選擇異步I/O也就瓜熟蒂落,從後端作到異步,提高資源響應速度,那麼隨以前端的用戶體驗也就會更好node

                                    

2. 系統資源

一組任務須要被執行,能夠經過兩種方式:單線程串行執行,多線程並行執行。

單線程串行執行,問題是:同步阻塞! I/O須要等待X步結束,才能進行到X+1步 - 緣由是早期分時系統:cpu輪流給不一樣用戶服務(服務的時間單位是時間片),給A服務完了第x步,可能就去給B服務第y步,以後才又回到屬於給A服務的時間片,而後再給A服務x+1步(這也能看出來爲啥I/O須要等待,上一步結束才能執行下一步)。爲了繼續執行A的操做,從x到x+1步驟的上下文就須要系統維護和交換,那麼當進程不少,就會形成性能的降低。慢的任務就會拖慢整個處理進度- 這樣難道一無可取麼,並非,好處是順序編程,邏輯比較容易,易於表達 。

多線程並行執行,問題是:編程時要考慮鎖,狀態同步的問題,稍有不慎,家毀人亡! 

所以,node.js的解決方案是:利用單線程,遠離多線程死鎖、狀態同步等問題;利用異步I/O,讓單線程遠離阻塞,以更好地使用CPU。(《深淺》原句)web

                                 

3. 應用場景

node.js特色與其應用場景我感受互爲問題與答案,考慮到web app是當今最多見的I/O密集型任務,node.js選擇了異步I/O,單線程以及事件驅動,來加強性能。同時,也正是由於node.js
的這些特色,使得它更加適合I/O密集型的應用場景。(關於node.js是否適合計算密集型任務,《深淺》中作了解釋與對比) 

---------------------------------------------------------------------編程

下面是另外幾點令我印象深入的地方:後端

  • 《深淺》還提到:爲了提高性能增長進程數量,這種方法是沒法提高資源利用率。他用到了『加三倍服務器』的例子,下面是我從豆瓣上找到的一個解釋:(加三倍服務器是否能提高性能)要看系統自己的架構,不必定增長三倍服務器就能檔得住三倍的用戶一塊兒來點的。由於服務器增多以後,其間通訊的成本也增長了,並且若是存在中心節點,那麼那幾個節點仍是會變成瓶頸。跟高速公路堵車對比,加服務器並非「四車道變八車道」那麼簡單,極可能多修幾條路之後1)十字路口也變多了2)支路多了之後主幹道堵得更厲害。」 
  • 若是深究異步I/O這個東西,《深淺》第三章作了更加細緻的講解,涉及到了異步的幾種實現方式,以及Node是怎麼實現異步I/O的。原來以前說的異步,是理想的非阻塞異步I/O: 


                                          (出自《深刻淺出node.js》)服務器

       真正到了實現的時候,Node實際上是用了多線程的方式模擬出來這一理想的效果。 


                                          (出自《深刻淺出node.js》)
網絡

     等等,多線程?Node不是JavaScript,是單線程麼,上面特色不說了是單線程麼?是否是說漏嘴了。那必須不是,《深淺》書中提到,Node的單線程指的JavaScript運行在單線程中,而實現Node的異步I/O功能的則是線程池/多線程。 
  • node.js既然有異步I/O的特色,是否是就能夠肆意妄爲了,只要異步就必定非阻塞呢?答案確定是不啊(考這麼多年試:像這種極端的問題,答案確定是否認的)。若是咱們在主線程作過多的任務,或者不少計算密集型任務,那麼可能會致使主線程的卡死,影響整個程序的性能,這不就阻塞你異步的腳步了。


若是有什麼地方總結的不對,但願你們一塊兒交流!多線程

相關文章
相關標籤/搜索