Node.js入門簡述

有關Node.js的技術報道越來越多,Node.js的寫法也是五花八門,有寫成NodeJS的,有寫成Nodejs的,到底哪一種寫法最標準呢,我們不妨遵循官方的說法。在Node.js的官方網站上,一直將其項目稱之爲”Node“或者”Node.js“,沒有發現其他的說法,”Node“用的最多,考慮到Node這個單詞的意思和用途太廣泛,容易讓開發人員誤解,我們採用了第二種稱呼——”Node.js“,js的後綴點出了Node項目的本意,其他的名稱五花八門,沒有確切的出處,我們不推薦使用。

Node.js不是JS應用、而是JS運行平臺

看到Node.js這個名字,初學者可能會誤以爲這是一個Javascript應用,事實上,Node.js採用C++語言編寫而成,是一個Javascript的運行環境。爲什麼採用C++語言呢?據Node.js創始人Ryan Dahl回憶,他最初希望採用Ruby來寫Node.js,但是後來發現Ruby虛擬機的性能不能滿足他的要求,後來他嘗試採用V8引擎,所以選擇了C++語言。既然不是Javascript應用,爲何叫.js呢?因爲Node.js是一個Javascript的運行環境。提到Javascript,大家首先想到的是日常使用的瀏覽器,現代瀏覽器包含了各種組件,包括渲染引擎、Javascript引擎等,其中Javascript引擎負責解釋執行網頁中的Javascript代碼。作爲Web前端最重要的語言之一,Javascript一直是前端工程師的專利。不過,Node.js是一個後端的Javascript運行環境(支持的系統包括*nux、Windows),這意味着你可以編寫系統級或者服務器端的Javascript代碼,交給Node.js來解釋執行,簡單的命令類似於:

#node helloworld.js

Node.js採用了Google Chrome瀏覽器的V8引擎,性能很好,同時還提供了很多系統級的API,如文件操作、網絡編程等。瀏覽器端的Javascript代碼在運行時會受到各種安全性的限制,對客戶系統的操作有限。相比之下,Node.js則是一個全面的後臺運行時,爲Javascript提供了其他語言能夠實現的許多功能。

Node.js採用事件驅動、異步編程,爲網絡服務而設計

事件驅動這個詞並不陌生,在某些傳統語言的網絡編程中,我們會用到回調函數,比如當socket資源達到某種狀態時,註冊的回調函數就會執行。Node.js的設計思想中以事件驅動爲核心,它提供的絕大多數API都是基於事件的、異步的風格。以Net模塊爲例,其中的net.Socket對象就有以下事件:connect、data、end、timeout、drain、error、close等,使用Node.js的開發人員需要根據自己的業務邏輯註冊相應的回調函數。這些回調函數都是異步執行的,這意味着雖然在代碼結構中,這些函數看似是依次註冊的,但是它們並不依賴於自身出現的順序,而是等待相應的事件觸發。事件驅動、異步編程的設計(感興趣的讀者可以查閱筆者的另一篇文章《Node.js的異步編程風格》),重要的優勢在於,充分利用了系統資源,執行代碼無須阻塞等待某種操作完成,有限的資源可以用於其他的任務。此類設計非常適合於後端的網絡服務編程,Node.js的目標也在於此。在服務器開發中,併發的請求處理是個大問題,阻塞式的函數會導致資源浪費和時間延遲。通過事件註冊、異步函數,開發人員可以提高資源的利用率,性能也會改善。

從Node.js提供的支持模塊中,我們可以看到包括文件操作在內的許多函數都是異步執行的,這和傳統語言存在區別,而且爲了方便服務器開發,Node.js的網絡模塊特別多,包括HTTP、DNS、NET、UDP、HTTPS、TLS等,開發人員可以在此基礎上快速構建Web服務器。以簡單的helloworld.js爲例:

var http = require('http');

http.createServer(function (req, res) {

    res.writeHead(200, {'Content-Type': 'text/plain'});

    res.end('Hello World\n');

}).listen(80, "127.0.0.1");

上面的代碼搭建了一個簡單的http服務器(運行示例部署在http://helloworld.cnodejs.net/中,讀者可以訪問),在本地監聽80端口,對於任意的http請求,服務器都返回一個頭部狀態碼爲200、Content-Type’值爲text/plain’的”Hello World“文字響應。從這個小例子中,我們可以看出幾點:

Node.js的網絡編程比較便利,提供的模塊(在這裏是http)開放了容易上手的API接口,短短几行代碼就可以構建服務器。

體現了事件驅動、異步編程,在createServer函數的參數中指定了一個回調函數(採用Javascript的匿名函數實現),當有http請求發送過來時,Node.js就會調用該回調函數來處理請求並響應。當然,這個例子相對簡單,沒有太多的事件註冊,在以後的文章中讀者會看到更多的實際例子。

Node.js的特點

下面我們來說說Node.js的特點。事件驅動、異步編程的特點剛纔已經詳細說過了,這裏不再重複。

Node.js的性能不錯。按照創始人Ryan Dahl的說法,性能是Node.js考慮的重要因素,選擇C++和V8而不是Ruby或者其他的虛擬機也是基於性能的目的。Node.js在設計上也是比較大膽,它以單進程、單線程模式運行(很吃驚,對吧?這和Javascript的運行方式一致),事件驅動機制是Node.js通過內部單線程高效率地維護事件循環隊列來實現的,沒有多線程的資源佔用和上下文切換,這意味着面對大規模的http請求,Node.js憑藉事件驅動搞定一切,習慣了傳統語言的網絡服務開發人員可能對多線程併發和協作非常熟悉,但是面對Node.js,我們需要接受和理解它的特點。由此我們是否可以推測出這樣的設計會導致負載的壓力集中在CPU(事件循環處理?)而不是內存(還記得Java虛擬機拋出OutOfMemory異常的日子嗎?),眼見爲實,不如來看看淘寶共享數據平臺團隊對Node.js的性能測試:

物理機配置:RHEL 5.2、CPU 2.2GHz、內存4G

Node.js應用場景:MemCache代理,每次取100字節數據

連接池大小:50

併發用戶數:100

測試結果(socket模式):內存(30M)、QPS(16700)、CPU(95%)

從上面的結果,我們可以看到在這樣的測試場景下,qps能夠達到16700次,內存僅佔用30M(其中V8堆佔用22M),CPU則達到95%,可能成爲瓶頸。此外,還有不少實踐者對Node.js做了性能分析,總的來說,它的性能讓人信服,也是受歡迎的重要原因。既然Node.js採用單進程、單線程模式,那麼在如今多核硬件流行的環境中,單核性能出色的Node.js如何利用多核CPU呢?創始人Ryan Dahl建議,運行多個Node.js進程,利用某些通信機制來協調各項任務。目前,已經有不少第三方的Node.js多進程支持模塊發佈,專欄後面的文章會詳細講述Node.js在多核CPU下的編程。

Node.js的另一個特點是它支持的編程語言是Javascript。關於動態語言和靜態語言的優缺點比較在這裏不再展開討論。只說三點:

Javascript作爲前端工程師的主力語言,在技術社區中有相當的號召力。而且,隨着Web技術的不斷髮展,特別是前端的重要性增加,不少前端工程師開始試水”後臺應用“,在許多采用Node.js的企業中,工程師都表示因爲習慣了Javascript,所以選擇Node.js。

Javascript的匿名函數和閉包特性非常適合事件驅動、異步編程,從helloworld例子中我們可以看到回調函數採用了匿名函數的形式來實現,很方便。閉包的作用則更大,看下面的代碼示例:

var hostRequest = http.request(requestOptions,function(response) {

    var responseHTML ='';

    response.on('data', function (chunk) {

        responseHTML = responseHTML + chunk;

    });

    response.on('end',function(){

        console.log(responseHTML);

        // do something useful

   });

});

在上面的代碼中,我們需要在end事件中處理responseHTML變量,由於Javascript的閉包特性,我們可以在兩個回調函數之外定義responseHTML變量,然後在data事件對應的回調函數中不斷修改其值,並最終在end事件中訪問處理。

Javascript在動態語言中性能較好,有開發人員對Javacript、Python、Ruby等動態語言做了性能分析,發現Javascript的性能要好於其他語言,再加上V8引擎也是同類的佼佼者,所以Node.js的性能也受益其中。

Node.js發展簡史

2009年2月,Ryan Dahl在博客上宣佈準備基於V8創建一個輕量級的Web服務器並提供一套庫。

2009年5月,Ryan Dahl在GitHub上發佈了最初版本的部分Node.js包,隨後幾個月裏,有人開始使用Node.js開發應用。

2009年11月和2010年4月,兩屆JSConf大會都安排了Node.js的講座。

2010年年底,Node.js獲得雲計算服務商Joyent資助,創始人Ryan Dahl加入Joyent全職負責Node.js的發展。

2011年7月,Node.js在微軟的支持下發布Windows版本。

文章來源:http://mingkr.com/nodejs-intro

文章網站首頁:http://mingkr.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章