1. 程式人生 > >Node.js究竟是什麼

Node.js究竟是什麼

一個 “編碼就緒” 伺服器

Node是一個伺服器端 JavaScript直譯器,它將改變伺服器應該如何工作的概念。它的目標是幫助程式設計師構建高度可伸縮的應用程式,編寫能夠處理數萬條同時連線到一個(只有一個)物理機的連線程式碼。

簡介

如果您聽說過 Node,或者閱讀過一些文章,宣稱 Node 是多麼多麼的棒,那麼您可能會想:“Node 究竟是什麼東西?” 即便是在參閱Node 的主頁之後,您甚至可能還是不明白 Node為何物?Node 肯定不適合每個程式設計師,但它可能是某些程式設計師一直苦苦追尋的東西。

為試圖解釋什麼是Node.js,本文將簡要介紹一些背景資訊:它要解決的問題,它如何工作,如何執行一個簡單應用程式,最後,Node在什麼情況下是一個好的解決方案。本文不涉及如何編寫一個複雜的 Node 應用程式,也不是一份全面的 Node 教程。閱讀本文應該有助於您決定是否應該繼續學習Node,以便將其用於您的業務.

Node 旨在解決什麼問題?

Node 公開宣稱的目標是 “旨在提供一種簡單的構建可伸縮網路程式的方法”。當前的伺服器程式有什麼問題?我們來做個數學題。在 Java PHP 這類語言中,每個連線都會生成一個新執行緒,每個新執行緒可能需要 2 MB的配套記憶體。在一個擁有 8 GB RAM 的系統上,理論上最大的併發連線數量是 4,000個使用者。隨著您的客戶群的增長,如果希望您的 Web 應用程式支援更多使用者,那麼,您必須新增更多伺服器。當然,這會增加伺服器成本、流量成本和人工成本等成本。除這些成本上升外,還有一個潛在技術問題,即使用者可能針對每個請求使用不同的伺服器,因此,任何共享資源都必須在所有伺服器之間共享。鑑於上述所有原因,整個

Web應用程式架構(包括流量、處理器速度和記憶體速度)中的瓶頸是:伺服器能夠處理的併發連線的最大數量。

Node解決這個問題的方法是:更改連線到伺服器的方式。每個連線發射一個在 Node 引擎的程序中執行的事件,而不是為每個連線生成一個新的 OS執行緒(併為其分配一些配套記憶體)。Node 聲稱它絕不會死鎖,因為它根本不允許使用鎖,它不會直接阻塞 I/O 呼叫。Node還宣稱,執行它的伺服器能支援數萬個併發連線。

現在您有了一個能處理數萬個併發連線的程式,那麼您能通過Node 實際構建什麼呢?如果您有一個 Web 應用程式需要處理這麼多連線,那將是一件很 “恐怖” 的事!那是一種 “如果您有這個問題,那麼它根本不是問題”的問題。在回答上面的問題之前,我們先看看 Node 的工作原理以及它的設計執行方式。

Node 肯定不是什麼?

沒錯,Node 是一個伺服器程式。但是,基礎 Node 產品肯定 Apache Tomcat。本質上,那些伺服器“安裝就緒型”務器產品,支援立即部署應用程式。通過這些產品,您可以在一分鐘內啟動並執行一個伺服器。Node肯定不是這種產品。Apache能通過新增一個 PHP 模組來允許開發人員建立動態 Web頁,新增一個 SSL 模組來實現安全連線,與此類似,Node也有模組概念,允許向 Node 核心新增模組。實際上,可供選擇的用於 Node的模組有數百個之多,社群在建立、釋出和更新模組方面非常活躍,一天甚至可以處理數十個模組。本文後面將討論 Node的整個模組部分。

Node 如何工作?

Node本身執行 V8 JavaScript。等等,伺服器上的 JavaScript?沒錯,您沒有看錯。對於只在客戶機上使用 JavaScript的程式設計師而言,伺服器端 JavaScript 可能是一個新概念,但這個概念本身並非遙不可及,因此為何不能在伺服器上使用客戶機上使用的程式語言?

什麼是V8?V8 JavaScript 引擎是 Google 用於其 Chrome 瀏覽器的底層 JavaScript 引擎。很少有人考慮 JavaScript在客戶機上實際做了些什麼?實際上,JavaScript 引擎負責解釋並執行程式碼。Google 使用 V8 建立了一個用 C++編寫的超快直譯器,該直譯器擁有另一個獨特特徵;您可以下載該引擎並將其嵌入任何應用程式。V8 JavaScript 引擎並不僅限於在一個瀏覽器中執行。因此,Node實際上會使用 Google 編寫的 V8 JavaScript引擎,並將其重建為可在伺服器上使用。太完美了!既然已經有一個不錯的解決方案可用,為何還要建立一種新語言呢?

事件驅動程式設計

許多程式設計師接受的教育使他們認為,面向物件程式設計是完美的程式設計設計,這使得他們對其他程式設計方法不屑一顧。Node使用了一個所謂的事件驅動程式設計模型。

清單 1. 客戶端上使用 jQuery 的事件驅動程式設計

// jQuery code on the client-side showing howEvent-Driven programming works

// When a button is pressed, anEvent occurs - deal with it
// directly right here in an anonymous function, where all the
// necessary variables are present and can be referenceddirectly
$("#myButton").click(function(){
     if($("#myTextField").val() != $(this).val())
         alert("Field must matchbutton text");
});

實際上,伺服器端和客戶端沒有任何區別。沒錯,這沒有按鈕點選操作,也沒有向文字欄位鍵入的操作,但在一個更高的層面上,事件正在發生。一個連線被建立,這是一個事件!資料通過連線進行接收,這也是一個事件!資料通過連線停止,這還是一個事件!

為什麼這種設定型別對 Node很理想?JavaScript是一種很棒的事件驅動程式語言,因為它允許使用匿名函式和閉包,更重要的是,任何寫過程式碼的人都熟悉它的語法。事件發生時呼叫的回撥函式可以在捕獲事件處進行編寫。這樣可以使程式碼容易編寫和維護,沒有複雜的面向物件框架,沒有介面,沒有過度設計的可能性。只需監聽事件,編寫一個回撥函式,其他事情都可以交給系統處理!

Node 對什麼有好處?

到此為止,您可能能夠回答“Node 是什麼” 這個問題了,但您可能還有一個問題:“Node 有什麼用途?” 這是一個需要提出的重要問題,因為肯定有些東西能受益於 Node。

它對什麼有好處?

正如您此前所看到的,Node非常適合以下情況:在響應客戶端之前,您預計可能有很高的流量,但所需的伺服器端邏輯和處理不一定很多。Node 表現出眾的典型示例包括:

RESTful API
提供 RESTful API Web服務接收幾個引數,解析它們,組合一個響應,並返回一個響應(通常是較少的文字)給使用者。這是適合 Node的理想情況,因為您可以構建它來處理數萬條連線。它仍然不需要大量邏輯;它本質上只是從某個資料庫中查詢一些值並將它們組成一個響應。由於響應是少量文字,入站請求也是少量的文字,因此流量不高,一臺機器甚至也可以處理最繁忙的公司的 API需求。

Twitter佇列
想像一下像 Twitter這樣的公司,它必須接收 tweets並將其寫入資料庫。實際上,每秒幾乎有數千條 tweet達到,資料庫不可能及時處理高峰時段所需的寫入數量。Node成為這個問題的解決方案的重要一環。如您所見,Node能處理數萬條入站 tweet。它能快速而又輕鬆地將它們寫入一個記憶體排隊機制(例如 memcached),另一個單獨程序可以從那裡將它們寫入資料庫。Node在這裡的角色是迅速收集 tweet,並將這個資訊傳遞給另一個負責寫入的程序。想象一下另一種設計(常規 PHP伺服器會自己嘗試處理對資料庫本身的寫入):每個 tweet都會在寫入資料庫時導致一個短暫的延遲,因為資料庫呼叫正在阻塞通道。由於資料庫延遲,一臺這樣設計的機器每秒可能只能處理 2000條入站 tweet。每秒處理 100萬條 tweet則需要 500個伺服器。相反,Node能處理每個連線而不會阻塞通道,從而能夠捕獲儘可能多的 tweets。一個能處理 50,000 tweetNode機器僅需 20臺伺服器即可。

電子遊戲統計資料
如果您線上玩過《使命召喚》這款遊戲,當您檢視遊戲統計資料時,就會立即意識到一個問題:要生成那種級別的統計資料,必須跟蹤海量資訊。這樣,如果有數百萬玩家同時線上玩遊戲,而且他們處於遊戲中的不同位置,那麼很快就會生成海量資訊。Node是這種場景的一種很好的解決方案,因為它能採集遊戲生成的資料,對資料進行最少的合併,然後對資料進行排隊,以便將它們寫入資料庫。使用整個伺服器來跟蹤玩家在遊戲中發射了多少子彈看起來很愚蠢,如果您使用 Apache這樣的伺服器,可能會有一些有用的限制;但相反,如果您專門使用一個伺服器來跟蹤一個遊戲的所有統計資料,就像使用執行 Node的伺服器所做的那樣,那看起來似乎是一種明智之舉。

Node 模組

儘管不是本文最初計劃討論的主題,但應廣大讀者要求,本文已經擴充套件為包含一個 Node Modules 和 Node PackageManager 簡介。正如已經習慣使用 Apache 的開發人員那樣,您也可以通過安裝模組來擴充套件 Node 的功能。但是,可用於 Node 的模組極大地增強了這個產品,那些模組非常有用,將使用 Node 的開發人員通常會安裝幾個模組。因此,模組也就變得越來越重要,甚至成為整個產品的一個關鍵部分。

在 “參考資料”部分,我提供了一個指向模組頁面的連結,該頁面列示了所有可用模組。為了展示模組能夠提供的可能性,我在數十個可用模組中包含了以下幾個模組:一個用於編寫動態建立的頁面(比如PHP),一個用於簡化 MySQL 使用,一個用於幫助使用WebSockets,還有一個用來協助文字和引數解析的模組。我不會詳細介紹這些模組,這是因為這篇概述文章旨在幫助您瞭解 Node並確定是否需要深入學習(再次重申),如果需要,那麼您肯定有機會用到這些可用模組。

另外,Node 的一個特性是 NodePackage Module,這是一個內建功能,用於安裝和管理 Node模組。它自動處理依賴項,因此您可以確定:您想要安裝的任何模組都將正確安裝幷包含必要的依賴項。它還支援將您自己的模組釋出到 Node社群,假如您選擇加入社群並編寫自己的模組的話。您可以將 NPM 視為一種允許輕鬆擴充套件 Node 功能的方法,不必擔心這會破壞您的 Node安裝。同樣,如果您選擇深入學習 Node,那麼 NPM 將是您的 Node 解決方案的一個重要組成部分。

結束語

閱讀本文之後,您在本文開頭遇到的問題“Node.js 究竟是什麼東西?”應該已經得到了解答,您應該能通過幾個清晰簡潔的句子回答這個問題。如果這樣,那麼您已經走到了許多程式設計師的前面。我和許多人都談論過 Node,但他們對 Node究竟用於做什麼一直很迷惑。可以理解,他們具有的是 Apache 的思維方式,認為伺服器就是一個應用程式,將 HTML檔案放入其中,一切就會正常運轉。由於大多數程式設計師都熟悉 Apache 及其用途,因此,描述 Node 的最簡單方法就是將它與 Apache 進行比較。Node是一個程式,能夠完成 Apache 能夠完成的所有任務(藉助一些模組),而且,作為一個可以將其作為基礎進行構建的可擴充套件 JavaScript 平臺,Node還能完成更多的任務。

從本文可以看出,Node完成了它提供高度可伸縮伺服器的目標。它使用了 Google 的一個非常快速的 JavaScript 引擎,即 V8引擎。它使用一個事件驅動設計來保持程式碼最小且易於閱讀。所有這些因素促成了 Node 的理想目標,即編寫一個高度可伸縮的解決方案變得比較容易。

與理解Node什麼同樣重要的是,理解它不是什麼。Node並不只是 Apache 的一個替代品,它旨在使PHP Web應用程式更容易伸縮。事實遠非如此。儘管Node 還處於初始階段,但它發展得非常迅速,社群參與度非常高,社群成員建立了大量優秀模組,一年之內,這個不斷髮展的產品就有可能出現在您的企業中.