Node.js到底是什麼?

   Node.js到底是什麼?     html

Node.js到底是什麼?

做者:koala 一個有趣的人
文章同步到github博客:https://github.com/koala-coding/goodBlog前端

前言node

若是你有必定的前端基礎,好比 `HTML、CSS、JavaScript、jQuery;那麼,Node.js 能讓你以最低的成本快速過渡成爲一個全棧工程師(我稱這個全棧爲僞全棧,我認爲的全棧也要精通數據庫,不喜勿噴),從而觸及後端和移動端的開發。固然,Node.js也不是萬能的、也不是說學了它就能夠徹底取代後端的其餘開發語言,它有本身的使命和擅長的應用領域。git

除此以外如今很是火熱的 Vue.js,Rect.js ,等不少數據層動態交互優先選用了Node.js,一些比較流行的打包工具也是如此;綜上,爲你爲何要學習它又增長了一大理由。程序員

Node.js 和傳統的後端語言(好比PHP、JAVA等)相比,各有優缺點,各自擅長領域和側重點不一樣,所以,各有千秋、各有需求市場。Node.js 讓咱們進行後端開發多了一種便捷的手段。因此你們也不要總說哪些語言是最好的,各有各的使命,嘿嘿。github

Node.js的特色web

非阻塞異步io面試

例如,當在訪問數據庫取得數據的時候,須要一段時間。在傳統的單線程處理機制中,在執行了訪問數據庫代碼以後,整個線程都將暫停下來,等待數據庫返回結果,才能執行後面的代碼。也就是說,I/O阻塞了代碼的執行,極大地下降了程序的執行效率。數據庫

因爲 Node.js 中採用了非阻塞型I/O機制,所以在執行了訪問數據庫的代碼以後,將當即轉而執行其後面的代碼,把數據庫返回結果的處理代碼放在回調函數中,從而提升了程序的執行效率。npm

當某個I/O執行完畢時,將以事件的形式通知執行I/O操做的線程,線程執行這個事件的回調函數。爲了處理異步I/O,線程必須有事件循環,不斷的檢查有沒有未處理的事件,依次予以處理。

阻塞模式下,一個線程只能處理一項任務,要想提升吞吐量必須經過多線程。而非阻塞模式下,一個線程永遠在執行計算操做,這個線程的CPU核心利用率永遠是100%。因此,這是一種特別有哲理的解決方案:與其人多,可是好多人閒着;還不如一我的玩命,往死裏幹活兒。

單線程

在 Java、PHP 或者 .net 等服務器端語言中,會爲每個客戶端鏈接建立一個新的線程。而每一個線程須要耗費大約2MB內存。也就是說,理論上,一個8GB內存的服務器能夠同時鏈接的最大用戶數爲4000個左右。要讓Web應用程序支持更多的用戶,就須要增長服務器的數量,而 Web 應用程序的硬件成本固然就上升了。

Node.js不爲每一個客戶鏈接建立一個新的線程,而僅僅使用一個線程。當有用戶鏈接了,就觸發一個內部事件,經過非阻塞I/O、事件驅動機制,讓 Node.js 程序宏觀上也是並行的。使用 Node.js ,一個8GB內存的服務器,能夠同時處理超過4萬用戶的鏈接。

另外,單線程帶來的好處,操做系統徹底再也不有線程建立、銷燬的時間開銷。可是單線程也有不少弊端,會在 Node.js 的弊端詳細講解,請繼續看。

事件驅動

在 Node 中,客戶端請求創建鏈接,提交數據等行爲,會觸發相應的事件。在 Node 中,在一個時刻,只能執行一個事件回調函數,可是在執行一個事件回調函數的中途,又有其餘事件產生,能夠轉而處理其餘事件(好比,又有新用戶鏈接了),而後返回繼續執行原事件的回調函數,這種處理機制,稱爲「事件環」機制。

Node.js 底層是 C++(V8也是C++寫的)。底層代碼中,近半數都用於事件隊列、回調函數隊列的構建。用事件驅動來完成服務器的任務調度,這是鬼才才能想到的。針尖上的舞蹈,用一個線程,擔負起了處理很是多的任務的使命。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 

注意這裏的事件循環,也能夠說是 Node.js 的一個精髓所在,下面引用一段 Node.js 官網的內容

   ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

引用Node官網中的一段內容:

注意:每一個框將被稱爲事件循環的「階段」。
每一個階段都有一個要執行的回調FIFO隊列。雖然每一個階段都以其本身的方式特殊,但一般狀況下,當事件循環進入給定階段時,它將執行特定於該階段的任何操做,而後在該階段的隊列中執行回調,直到隊列耗盡或最大回調數量爲止已執行。當隊列耗盡或達到回調限制時,事件循環將移至下一階段,依此類推。
關於事件循環是一個核心點,常常會被面試官考具體執行輸出的問題,你們能夠看個人這篇文章

跨平臺

起初,Node 只能在 Linux 平臺上運行。後來隨着Node的發展,微軟注意到了它的存在,並投入了一個團隊幫助 Node 實現 Windows 平臺的兼容,在v0.6.0版本發佈時,Node 已經可以直接在 Window 平臺運行了。 Node 是基於libuv實現跨平臺的。

Node.js的弊端

單線程帶來的弊端

Node.js中有一個特色就是單線程,它帶來了不少好處,可是它也有弊端,單線程弱點以下。

  1. 沒法利用多核CPU
  2. 錯誤會引發整個應用退出沒法繼續調用異步I/O
  3. 大量計算佔用CPU致使沒法繼續調用異步I/O

以上確實是Node的弊端,可是都會有一些對應的解決方案:

弊端1:解決方案

  • (1)一些管理工具好比pm2,forever 等均可以實現建立多進程解決多核 CUP 的利用率問題。
  • (2)在v0.8版本以前,實現多進程可使用child_process
  • (3)在v0.8版本以後,可使用cluster模塊,經過主從模式,建立多個工做進程解決多核CPU的利用率問題。

弊端2:解決方案

  • (1)Nnigx反向代理,負載均衡,開多個進程,綁定多個端口;
  • (2) 一些管理工具好比pm2,forever 等均可以實現進程監控,錯誤自動重啓等
  • (3)開多個進程監聽同一個端口,使用Node提供的cluster模塊;
  • (4)未出現cluster以前,也可使用child_process,建立多子線程監聽一個端口。
  • (5)這裏說明下,有上面的這些解決方案,可是寫node後端代碼的時候,異常拋出try catch顯得格外有必要。

弊端3:解決方案

  • (1)能夠把大量的密集計算像上面同樣拆分紅多個子線程計算
  • 可是若是不容許拆分,想計算100萬的大數據,在一個單線程中,Node確實顯得無能爲力,這自己就是V8內存限制的弊端。

說明:child_process與cluster模塊我會單獨拿一篇文章來說。
值得開心的是上面這些弊端隨着Node的版本更新,和新的api模塊出現,好像解決了這些弊端。

調試

用過node的人可能第一時間就會想到debug太難了,沒有stack trace,所以調試比較困難。

Node社區中的npm包

Node.js社區有不少包品質參差不齊、若是你想偷懶而又恰好npm了一個有問題的包你就很麻煩,由於代碼是開源的,只能本身調試了。

Node.js的應用場景

介紹了Node.js的特色和弊端,再說一下Node.js的應用場景。

Node.js適合用來開發什麼樣的應用程序呢?

善於I/O,不善於計算。由於Node.js最擅長的就是任務調度,若是你的業務有不少的 CPU 計算,實際上也至關於這個計算阻塞了這個單線程,就不太適合Node開發,可是也不是沒有解決方案,只是說不太適合。

當應用程序須要處理大量併發的I/O,而在向客戶端發出響應以前,應用程序內部並不須要進行很是複雜的處理的時候,Node.js很是適合。Node.js也很是適合與web socket配合,開發長鏈接的實時交互應用程序。

具體場景能夠表現爲以下:

  • 第一大類:用戶表單收集系統、後臺管理系統、實時交互系統、考試系統、聯網軟件、高併發量的web應用程序;
  • 第二大類:基於web、canvas等多人聯網遊戲;
  • 第三大類:基於web的多人實時聊天客戶端、聊天室、圖文直播;
  • 第四大類:單頁面瀏覽器應用程序;
  • 第五大類:操做數據庫、爲前端和移動端提供基於json的API;
  • 第六大類,…

哪些大公司在用

  • 雅虎:雅虎開放了Cooktail框架,將YUI3這個前端框架的能力藉助Node延伸到了服務器端。
  • 騰訊:將Node應用到長鏈接,以提供實時功能。
  • 花瓣網,蘑菇街:經過socket.io實現實時通知。
  • 阿里:主要利用的是並行I/O這個性能,實現高效的分佈式,它們本身也出了不少Node框架
  • LinkedIn:移動網站也是使用的Node
  • 網易:遊戲領域對併發和實時要求很高,網易開源了Node的實時框架pomelo
  • 等等…

參考文章:本文部份內容來自樸靈老師的《深刻淺出Node.js》

文章同步到

程序員成長指北(ID:coder_growth)

相關文章
相關標籤/搜索