Node.js是什麼?

node.js是什麼?” ; “爲什麼我們要用node.js?”,別人一般會告訴你:node.js有非阻塞事件驅動I/O等特性,從而讓高併發(high concurrency)在的輪詢(Polling)和comet構建的應用中成爲可能。


瀏覽器給網站發請求的過程一直沒怎麼變過 : 

       當瀏覽器給網站發了請求。服務器收到了請求,然後開始搜尋被請求的資源。如果有需要,服務器還會查詢一下數據庫,最後把響應結果傳回瀏覽器。不過,在傳統的web服務器中(比如Apache),每一個請求都會讓服務器創建一個新的進程來處理這個請求。

       後來有了Ajax。我們就不用每次都請求一個完整的新頁面了,取而代之的是,每次只請求需要的部分頁面信息。這顯然是一個進步。但是比如你要建一個FriendFeed這樣的社交網站(類似人人網那樣的刷朋友新鮮事的網站),你的好友會隨時的推送新的狀態,然後你的新鮮事會實時自動刷新。要達成這個需求,我們需要讓用戶一直與服務器保持一個有效連接。目前最簡單的實現方法,就是讓用戶和服務器之間保持長輪詢(long polling)。

       HTTP請求不是持續的連接,你請求一次,服務器響應一次。長輪詢是一種利用HTTP模擬持續連接的技巧具體來說,只要頁面載入了,不管你需不需要服務器給你響應信息,你都會給服務器發一個Ajax請求。這個請求不同於一般的Ajax請求,服務器不會直接給你返回信息,而是它要等着,直到服務器覺得該給你發信息了,它纔會響應。比如,你的好友發了一條新鮮事,服務器就會把這個新鮮事當做響應發給你的瀏覽器,然後你的瀏覽器就刷新頁面了。瀏覽器收到響應刷新完之後,再發送一條新的請求給服務器,這個請求依然不會立即被響應。於是就開始重複以上步驟。

利用這個方法,可以讓瀏覽器始終保持等待響應的狀態。雖然以上過程依然只有非持續的Http參與,但是我們模擬出了一個看似持續的連接狀態

我們再看傳統的服務器(比如Apache)。每次一個新用戶連到你的網站上,你的服務器就得開一個連接。每個連接都需要佔一個進程,這些進程大部分時間都是閒着的(比如等着你好友發新鮮事,等好友發完纔給用戶響應信息。或者等着數據庫返回查詢結果什麼的)。雖然這些進程閒着,但是照樣佔用內存。這意味着,如果用戶連接數的增長到一定規模,你服務器沒準就要耗光內存直接癱了。


這種情況怎麼解決?解決方法就是剛纔上邊說的:非阻塞事件驅動。這些概念在我們談的這個情景裏面其實沒那麼難理解。你把非阻塞的服務器想象成一個loop循環,這個loop會一直跑下去。一個新請求來了,loop就接收這個請求並把這個請求傳給其他的進程(比如傳給一個搞數據庫查詢的進程),然後響應一個回調(callback)。完事了這loop就接着跑,接其他的請求。這樣下來。服務器就不會像之前那樣傻等着數據庫返回結果了。


如果數據庫把結果返回來了,loop就把結果傳回用戶的瀏覽器,接着繼續跑。在這種方式下,你的服務器的進程就不會閒着等着。從而在理論上說,同一時刻的數據庫查詢數量,以及用戶的請求數量就沒有限制了。服務器只在用戶那邊有事件發生的時候才響應,這就是事件驅動。


FriendFeed是用基於Python的非阻塞框架Tornado (知乎也用了這個框架) 來實現上面說的新鮮事功能的。不過,Node.js就比前者更妙了。Node.js的應用是通過javascript開發的,然後直接在Google的變態V8引擎上跑。用了Node.js,你就不用擔心用戶端的請求會在服務器裏跑了一段能夠造成阻塞的代碼了。因爲javascript本身就是事件驅動的腳本語言。你回想一下,在給前端寫javascript的時候,更多時候你都是在搞事件處理和回調函數。javascript本身就是給事件處理量身定製的語言。


Node.js還是處於初期階段。如果你想開發一個基於Node.js的應用,你應該會需要寫一些很底層代碼。但是下一代瀏覽器很快就要採用WebSocket技術了,從而長輪詢也會消失。在Web開發裏,Node.js這種類型的技術只會變得越來越重要。


以上。

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