NodeJS概述

NodeJS中文API

一.概述node

Node.js 是一種創建在Google Chrome’s v8 engine上的 non-blocking (非阻塞), event-driven (基於事件的) I/O平臺.數據庫

以事件驅動爲核心,單線程,單進程。Node.js 最大的特色就是採用異步式 I/O 與事件驅動的架構設計。對於高併發的解決方案,傳統的架構是多線程模型,也就是爲每一個業務邏輯提供一個系統線程,經過系統線程切換來彌補同步式 I/O 調用時的時間開銷。Node.js 使用的是單線程模型,對於全部 I/O 都採用異步式的請求方式,避免了頻繁的上下文切換。Node.js 在執行的過程當中會維護一個事件隊列,程序在執行時進入事件循環等待下一個事件到來,每一個異步式 I/O 請求完成後會被推送到事件隊列,等待程序進程進行處理。事件驅動機制是Node.js經過內部單線程高效率地維護事件循環隊列來實現的,沒有多線程的資源佔用和上下文切換,這意味着面對大規模的http請求,Node.js憑藉事件驅動搞定一切。由於Node是基於事件驅動和無阻塞的,因此很是適合處理併發請求。能夠經過運行多個Node.js進程的方式來有效利用多個CPU。編程

 

二.Node.js選擇的異步I/O方案

1.在Linux下,node.js靠libev和libeio配合使用來實現異步I/O。api

(1).什麼是libev?服務器

• libev是一個事件驅動庫,提供高性能事件循環網絡

• 主要用於事件驅動的網絡編程多線程

(2).什麼是libeio?架構

libeio爲C提供異步版本的POSIX API併發

• 主要提供文件I/O操做異步

• 異步操做經過線程實現

• libeio僅依賴pthread,跨平臺能力很是好

• 能夠和任何事件庫配合使用,好比libev 。

(3).爲何不用libev實現異步文件操做?

對於Regular File 來講,是不可以用採用 poll/epoll 的,即O_NOBLOCK 方式對於傳統文件句柄是無效的,也就是說咱們的 open ,read, mkdir 之類的Regular File操做一定會致使阻塞.

 

2.Windows有一種獨有的內核異步IO方案:IOCP。IOCP的思路是真正的異步I/O方案,調用異步方法,而後等待I/O完成通知。IOCP內部依舊是經過線程實現,不一樣在於這些線程由系統內核接手管理。IOCP的異步模型與Node.js的異步調用模型已經十分近似。

     

3.因爲Windows平臺和*nix平臺的差別,Node.js提供了libuv來做爲抽象封裝層,使得全部平臺兼容性的判斷都由這一層次來完成,保證上層的Node.js與下層的libeio/libev及IOCP之間各自獨立。Node.js在編譯期間會判斷平臺條件,選擇性編譯unix目錄或是win目錄下的源文件到目標程序中。

對於 POSIX①操做系統,libuv 經過封裝 libev 和 libeio 來利用 epoll 或 kqueue。而在 Windows 下,libuv 使用了 Windows 的 IOCP(Input/Output Completion Port,輸入輸出完成端口)機制,以在不一樣平臺下實現一樣的高性能。

① POSIX(Portable Operating System Interface)是一套操做系統 API 規範。通常而言,遵照 POSIX 規範的操做系統指的是 UNIX、Linux、Mac OS X 等。

arch

 

下面是Node.JS架構示意圖

1-2

 

三.異步式 I/O 與事件驅動

Node.js 的異步機制是基於事件的,全部的磁盤 I/O、網絡通訊、數據庫查詢都以非阻塞的方式請求,返回的結果由事件循環來處理。圖1-1 描述了這個機制。Node.js 進程在同一時刻只會處理一個事件,完成後當即進入事件循環檢查並處理後面的事件。這樣作的好處是,CPU 和內存在同一時間集中處理一件事,同時儘量讓耗時的 I/O 操做並行執行。對於低速鏈接攻擊,Node.js 只是在事件隊列中增長請求,等待操做系統的迴應,於是不會有任何多線程開銷,很大程度上能夠提升 Web 應用的健壯性,防止惡意攻擊。

1-1

圖1-1 事件循環

 

以在Windows平臺下的實現中,啓動Node.js時,便建立了一個基於IOCP的事件循環loop,並一直處於執行狀態。

uv_run(uv_default_loop());

每次循環中,它會調用IOCP相關的GetQueuedCompletionStatus方法檢查是否線程池中有執行完的請求,若是存在,poll操做會將請求對象加入到loop的pending_reqs_tail屬性上。 另外一邊這個循環也會不斷檢查loop對象上的pending_reqs_tail引用,若是有可用的請求對象,就取出請求對象的result屬性做爲結果傳遞給oncomplete_sym執行,以此達到調用JavaScript中傳入的回調函數的目的。 至此,整個異步I/O的流程完成結束。

事件循環和請求對象構成了Node.js的異步I/O模型的兩個基本元素,這也是典型的消費者生產者場景。在Windows下經過IOCP的GetQueuedCompletionStatus、PostQueuedCompletionStatus、QueueUserWorkItem方法與事件循環實。對於*nix平臺下,這個流程的不一樣之處在與實現這些功能的方法是由libeio和libev提供。

 

四.多線程阻塞服務器 vs 事件驅動、無阻塞服務器

clipboard

clipboard[1]

相關文章
相關標籤/搜索