《Node.js》之事件處理機制以及事件環機制(二)

傳統服務器與Node.js的比較編程

    傳統的服務器在面臨高併發的場景時,會使用多線程方案,服務器會爲客戶端的請求分配一個線程,使用同步的I/O,系統經過線程切換來彌補同步I/O調用過程當中的時間開銷。Apache就是使用的這種方式,因爲I/O操做會消耗比較多的時間,經過多線程的方式解決高併發的問題,難以實現高性能,可是能夠實現很複雜的邏輯。     可是大多數網站的服務端不須要太多的計算處理,收到請求以後交給其餘的服務進行處理,將處理結果返回給客戶端。所以Node.js會針對這樣的應用場景使用單線程模型進行處理,並不會爲每個客戶端的請求建立一個線程,而是經過一個線程處理全部的請求,而後對I/O操做進行異步處理,這樣的方式能夠減小建立、銷燬線程以及線程切換消耗的時間。安全

Node.js的事件處理機制服務器

    在Node.js中採用了非阻塞的I/O機制,在這種機制下應用程序所進行的處理都不會再結束以前阻礙其餘處理的進行。這些處理都是相互獨立的,每個事件處理完成以後,會執行一個回調函數。     Node.js在主線程裏面維護了一個事件隊列,當接到請求以後就會將請求做爲一個事件放在這個事件隊列中,而後繼續接受其餘的請求。當主線程空閒的時候就開始循環事件隊列。檢查隊列中是否有須要處理的事件,若是須要處理的事件不是I/O任務,就親自處理,經過回調函數返回到上層調用。若是是I/O任務,就從線程池裏面拿出一個線程處理這個事件,而且指定回調函數,而後繼續循環隊列中的其餘事件。多線程

Node.js事件環原理併發

    事件循環定義:當線程中的I/O任務完成以後就會執行指定的回調函數,而且將這個完成的事件放在事件隊列的尾部,等待事件循環,當主線程再次循環到這個事件的時候,就會直接處理而且返回給上層調用,這個過程就是事件循環(Event Loop)。Node.js運行的原理圖以下所示: 圖片1.png異步

這個圖是整個 Node.js 的運行原理,從左到右,從上到下,Node.js 被分爲了四層,分別是 應用層、V8引擎層、Node API層和LIBUV層。函數

  • 應用層:即 JavaScript 交互層,常見的就是 Node.js 的模塊,好比 http,fs。
  • V8引擎層:即利用 V8 引擎來解析JavaScript 語法,進而和下層 API 交互。
  • Node API層:爲上層模塊提供系統調用,通常是由 C 語言來實現,和操做系統進行交互。
  • LIBUV層:是跨平臺的底層封裝,實現了 事件循環、文件操做等,是 Node.js 實現異步的核心。     在Node.js的內部是經過線程池來完成I/O操做的,可是LIBUV層會針對不一樣的操做系統平臺的差別性實現了統一調用,Node.js的單線程指的是JavaScript運行在單線程中,並非說Node.js是單線程的,Node.js是一個多線程的平臺,可是對於JavaScript的處理是單線程的。

Node.js特色及適用性高併發

  • Node.js在處理I/O任務的時候,會把任務交給線程池來處理,高效簡單,所以Node.js適合用於處理I/O密集型的任務,可是不適合處理CPU密集型的任務,這是由於對於非I/O任務Node.js都是經過主線程親自計算的,前面的任務沒有處理完的狀況下就會致使後來的任務堆積,就會出現響應緩慢的狀況。即便是多核CPU在使用Node.js處理非I/O任務的時候,因爲Node.js只有一個事件循環隊列,因此只佔用一個CPU內核,可是其餘的內核都會處於空閒狀態,所以會形成響應緩慢,CPU資源浪費的狀況,因此Node.js不適合用於處理CPU密集型的任務。
  • Node.js還有一個優勢是線程安全,單線程的JavaScript運行方式保證了線程的安全,不用擔憂同一個變量被多個線程進行讀寫形成程序崩潰。同時也免去了在多線程編程中忘記對變量加鎖或者解鎖形成隱患。
相關文章
相關標籤/搜索