Node.js 究竟是什么?

在網上看到一篇介紹Node.js的文章,很好的介紹了Node.js

Michael Abernethy, 自由程序員, Freelancer ?2011 年 10 月 09 日 (最初于 2011 年 4 月 26 日)

Node.js 究竟是什么?

一個 “編碼就緒” 服務器

Node 是一個服務器端 JavaScript 解釋器,它將改變服務器應該如何工作的概念。它的目標是幫助程序員構建高度可伸縮的應用程序,編寫能夠處理數萬條同時連接到一個(只有一個)物理機的連接代碼。

?

本文的第一版發表后,文中談到的各種觀點在社區中引起了廣泛的討論。因此,本文作者修改了第一版,其中借鑒了社區成員提出的觀點。這種同行審閱和討論是開源世界的關鍵組成部分。感謝那些提出建設性意見的同行。

與所有開源項目一樣,Node.js 將繼續向前發展,開發人員將探索可以克服任何限制的新資源和新技術。按照慣例,我們鼓勵讀者親自嘗試新技術。

簡介

如果您聽說過 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 的事件驅動編程
1 // jQuery code on the client-side showing how Event-Driven programming works
2 
3 // When a button is pressed, an Event occurs - deal with it
4 // directly right here in an anonymous function, where all the
5 // necessary variables are present and can be referenced directly
6 $("#myButton").click(function(){
7      if ($("#myTextField").val() != $(this).val())
8          alert("Field must match button text");
9 });

?

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

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

示例 Node 應用程序

最后,我們來看一些代碼!讓我們將討論過的所有內容匯總起來,從而創建我們的第一個 Node 應用程序。我們已經知道,Node 對于處理高流量應用程序很理想,所以我們將創建一個非常簡單的 Web 應用程序,一個為實現最快速度而構建的應用程序。下面是 “老板” 交代的關于我們的樣例應用程序的具體要求:創建一個隨機數字生成器 RESTful API。這個應用程序應該接受一個輸入:一個名為 “number” 的參數。然后,應用程序返回一個介于 0 和該參數之間的隨機數字,并將生成的數字返回給調用者。由于 “老板” 希望該應用程序成為一個廣泛流行的應用程序,因此它應該能處理 50,000 個并發用戶。我們來看看以下代碼:

清單 2. Node 隨機數字生成器
// these modules need to be imported in order to use them.
// Node has several modules.  They are like any #include
// or import statement in other languages
var http = require("http");
var url = require("url");// The most important line in any Node file.  This function
// does the actual process of creating the server.  Technically,
// Node tells the underlying operating system that whenever a
// connection is made, this particular callback function should be
// executed.  Since we're creating a web service with REST API,
// we want an HTTP server, which requires the http variable
// we created in the lines above.
// Finally, you can see that the callback method receives a 'request'
// and 'response' object automatically.  This should be familiar
// to any PHP or Java programmer.
http.createServer(function(request, response) {// The response needs to handle all the headers, and the return codes// These types of things are handled automatically in server programs// like Apache and Tomcat, but Node requires everything to be done yourselfresponse.writeHead(200, {"Content-Type": "text/plain"});// Here is some unique-looking code.  This is how Node retrives// parameters passed in from client requests.  The url module// handles all these functions.  The parse function// deconstructs the URL, and places the query key-values in the// query object.  We can find the value for the "number" key// by referencing it directly - the beauty of JavaScript.var params = url.parse(request.url, true).query;var input = params.number;// These are the generic JavaScript methods that will create// our random number that gets passed back to the callervar numInput = new Number(input);var numOutput = new Number(Math.random() * numInput).toFixed(0);// Write the random number to response
     response.write(numOutput);// Node requires us to explicitly end this connection.  This is because// Node allows you to keep a connection open and pass data back and forth,// though that advanced topic isn't discussed in this article.
     response.end();// When we create the server, we have to explicitly connect the HTTP server to// a port.  Standard HTTP port is 80, so we'll connect it to that one.
}).listen(80);// Output a String to the console once the server starts up, letting us know everything
// starts up correctly
console.log("Random Number Generator Running...");

?

?

啟動應用程序

將上面的代碼放入一個名為 “random.js” 的文件中。現在,要啟動這個應用程序并運行它(以便創建 HTTP 服務器并監聽端口 80 上的連接),只需在您的命令提示中輸入以下命令:% node random.js。下面是服務器已經啟動并運行時看起來的樣子:

root@ubuntu:/home/moila/ws/mike# node random.js
Random Number Generator Running...

訪問應用程序

應用程序已經啟動并運行。Node 正在監聽所有連接,我們來測試一下。由于我們創建了一個簡單的 RESTful API,所以可以使用 Web 瀏覽器來訪問這個應用程序。鍵入以下地址(確保您已完成了上面的步驟):http://localhost/?number=27。

您的瀏覽器窗口將更改到一個介于 0 到 27 之間的隨機數字。單擊瀏覽器上的 “重新載入” 按鈕,您會得到另一個隨機數字。就是這樣,這就是您的第一個 Node 應用程序!

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 條 tweet 的 Node 機器僅需 20 臺服務器即可。

  • 電子游戲統計數據

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

Node 模塊

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

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

另外,Node 的一個特性是 Node Package 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 還處于初始階段,但它發展得非常迅速,社區參與度非常高,社區成員創建了大量優秀模塊,一年之內,這個不斷發展的產品就有可能出現在您的企業中。

轉載于:https://www.cnblogs.com/setukirin/p/6380967.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/393934.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/393934.shtml
英文地址,請注明出處:http://en.pswp.cn/news/393934.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

react中綁定點擊事件_在React中綁定事件處理程序的最佳方法

react中綁定點擊事件by Charlee Li通過李李 在React中綁定事件處理程序的最佳方法 (The best way to bind event handlers in React) Binding event handlers in React can be tricky (you have JavaScript to thank for that). For those who know the history of Perl and P…

json_decode php數組,json_decode轉化為數組加true,json_encode和json_decode區別

一、json_encode和json_decode區別1、json_encode:對象/數組 ---> json2、json_decode:json ---> 對象/數組二、json_decode轉化為數組轉化為數組時,第二個參數很重要:不加true會以PHP對象輸出, 加true輸出PHP數組&#xff…

leetcode1219. 黃金礦工(回溯)

你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,并用大小為 m * n 的網格 grid 進行了標注。每個單元格中的整數就表示這一單元格中的黃金數量;如果該單元格是空的,那么就是 0。 為了使收益最大化,礦工…

【無刪減】Python老司機收藏夾的17個國外免費學習網站

用Python編寫代碼一點都不難,事實上它一直被贊譽為最容易學的編程語言。如果你準備學習web開發, Python是一個不錯的開始,甚至想做游戲的話,用Python來開發游戲的資源也有很多。這是快速學習這門語言的途徑之一。許多程序員都把Py…

iframe vue 前進 后退_vue常見面試題

1、說說你對 SPA 單頁面的理解,它的優缺點分別是什么?SPA( single-page application )僅在 Web 頁面初始化時加載相應的 HTML、JavaScript 和 CSS。一旦頁面加載完成,SPA 不會因為用戶的操作而進行頁面的重新加載或跳轉…

C#編寫運行在Linux環境下的采用Mediainfo來獲取多媒體文件信息的代碼

C#編寫運行在Linux環境下的采用Mediainfo來獲取多媒體文件信息的代碼 原文:C#編寫運行在Linux環境下的采用Mediainfo來獲取多媒體文件信息的代碼項目開始設計的是運行在windows下,所以一開始采用的是windows服務模式來獲取多媒體文件信息,后來要求調整為…

如何用chrome擴展將網頁變成黑底白字,用以保護視力

不知道有沒有科學依據,自己感覺黑底白字對視力好些,于是動手加個chrome擴展: 第一步:建個文件夾,名稱比如叫changeColor; 第二步:在changeColor文件夾中建三個文件:manifest.json 、 backgrou…

從零學習機器學習_機器學習:如何從零變英雄

從零學習機器學習以“為什么?”開頭 并以“我準備好了!”結尾 (Start with “Why?” and end with “I’m ready!”) If your understanding of A.I. and Machine Learning is a big question mark, then this is the blog post for you. Here, I gradu…

sqoop動態分區導入mysql,使用sqoop import從mysql往hive含分區表中導入數據的一些注意事項...

先看下面這條語句,它實現的功能是將特定日期的數據從mysql表中直接導入hive$ sqoop import \--connect jdbc:mysql://192.168.xx.xx:3306/db_name?useSSLfalse \--username xxx --password xxxxxx \--query "select d.id, d.callsign, d.sobt from t_flight_b…

leetcode面試題 08.04. 冪集(遞歸)

冪集。編寫一種方法,返回某集合的所有子集。集合中不包含重復的元素。 說明:解集不能包含重復的子集。 示例: 輸入: nums [1,2,3] 輸出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ] 代碼 class Solution {List&l…

gatsby_我如何使用Gatsby和Netlify建立博客

gatsbyby Pav Sidhu通過帕夫西杜(Pav Sidhu) 我如何使用Gatsby和Netlify建立博客 (How I Built My Blog Using Gatsby and Netlify) 您能說出更具標志性的二人??組合嗎? ? (Can you name a more iconic duo? ?) Years ago, whenever I built a stat…

交叉熵與相對熵

熵的本質是香農信息量()的期望。 現有關于樣本集的2個概率分布p和q,其中p為真實分布,q非真實分布。 按照真實分布p來衡量識別一個樣本的所需要的編碼長度的期望(即平均編碼長度)為:H(p)。 如果使用錯誤分布q來表示來自真實分布p的平均編碼長度…

menustrip

在對應菜單上點擊鼠標右鍵,插入,SEPARATOR 就可以了,然后可以選中拖動位置。轉載于:https://www.cnblogs.com/Echo529/p/6382302.html

直接排序

題目:使用直接排序法將下列數組(從小到大排序)思路:第一次:使用索引值為0的元素與其他位置的元素挨個比較一次,如果發現比0號索引值的元素小的,那么交換位置,第一輪下來最小值被放在…

leetcode78. 子集(回溯)

給定一組不含重復元素的整數數組 nums,返回該數組所有可能的子集(冪集)。 說明:解集不能包含重復的子集。 示例: 輸入: nums [1,2,3] 輸出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ] 代碼 class Solution {pub…

php字符串綜合作業,0418php字符串的操作

實例字符串函數(一):長度計算$siteName php中文網;//獲取內部字符編碼集$encoding mb_internal_encoding();//1、strlen($str):獲取字節表示的字符串長度//utf8模式下,一個中文字符用三個字節表示echo strlen($siteName),; //12//2、mb_strlen($str,$encoding)&…

如何處理JavaScript中的事件處理(示例和全部)

In this blog, I will try to make clear the fundamentals of the event handling mechanism in JavaScript, without the help of any external library like Jquery/React/Vue.在此博客中,我將嘗試在沒有任何外部庫(例如Jquery / React / Vue)的幫助下闡明JavaSc…

js 圖片預覽

//顯示選擇的圖片縮略圖function showImage(inputId,imageConfirmId,imageConfi){var imagedocument.getElementById(inputId).value.toLowerCase();if(!image){return;}var fileExtendimage.substr(image.lastIndexOf(".", image.length)1);if(!(fileExtend"jp…

什么是copyonwrite容器

2019獨角獸企業重金招聘Python工程師標準>>> CopyOnWrite容器即寫時復制的容器。通俗的理解是當往一個容器添加元素的時候,不直接往當前容器添加,而是先將當前容器進行Copy,復制出一個新的容器,然后新的容器里添加元素…

hystrix 源碼 線程池隔離_Hystrix源碼學習--線程池隔離

分析你的系統你所認識的分布式系統,哪些是可以進行垂直拆分的?拆分之后系統之間的依賴如何梳理?系統異構之后的穩定性調用如何保證?這些都是可能在分布式場景中面臨的問題。說個比較常見的問題,大家都知道秒殺系統&…