為什么我要用 Node.js? 案例逐一介紹
介紹
JavaScript 高漲的人氣帶來了很多變化,以至于如今使用其進(jìn)行網(wǎng)絡(luò)開發(fā)的形式也變得截然不同了。就如同在瀏覽器中一樣,現(xiàn)在我們也可以在服務(wù)器上運行 JavaScript ,從前端跨越到后端,這樣巨大的反差讓人難以想象,因為僅僅在幾年前Javascript 還如同 Flash 或者 Java applet 那樣嵌入網(wǎng)頁在沙箱環(huán)境中運行。
在深入Node.js之前,你可能需要閱讀和了解使用跨棧式JavaScript(JavaScript across the stack)帶來的好處,它統(tǒng)一了編程語言和數(shù)據(jù)格式(JSON),讓你能***地重用開發(fā)人員資源。由于這更多的是關(guān)于 JavaScript 的特點,這里就不過多討論它。但它確實是一個讓人在開發(fā)環(huán)節(jié)中使用 Node 的關(guān)鍵的優(yōu)點。
正如維基百科所說:“Node.js 是谷歌 V8 引擎、libuv平臺抽象層 以及主體使用 Javscript 編寫的核心庫三者集合的一個包裝外殼。” 除此之外,值得注意的是,Node.js 的作者瑞恩·達(dá)爾 (Ryan Dahl) 的目標(biāo)是創(chuàng)建具有實時推送能力的網(wǎng)站。在 Node.js 中,他給了開發(fā)者一個使用事件驅(qū)動來實現(xiàn)異步開發(fā)的優(yōu)秀解決方案。(注:V8是谷歌開發(fā)的,目前公認(rèn)最快的 Javascript 解析引擎,libuv 是一個開源的、為 Node 定制而生的跨平臺的異步 IO 庫。)
簡而言之:Node.js 在實時的 Web應(yīng)用上采用了基于 WebSocket 的推送技術(shù)。這意味著什么樣的革命性?Well,在經(jīng)過了20多年的基于無狀態(tài)的請求-返機(jī)制的無狀態(tài)交互之后,我們終于有了實時的,雙向連接的web應(yīng) 用,客戶端和服務(wù)器端都可以發(fā)起通信,能夠自由地交換數(shù)據(jù)。與此形成鮮明對比的是傳統(tǒng)的 web響應(yīng)模式,客戶端總是主動發(fā)起通信而服務(wù)端被動返回。此外,這些都是基于運行在標(biāo)準(zhǔn)80端口上的開放Web組件(HTML、CSS和JS)。
可能有人會說,我們已經(jīng)使用 Flash 和 Java Applet 的形式很多年了——但實際上,這些方式只是使用網(wǎng)絡(luò)將數(shù)據(jù)傳遞到客戶端上的沙箱環(huán)境。他們都是隔離運行的,而且經(jīng)常操作到需要額外的權(quán)限之類的非標(biāo)準(zhǔn)端口。
憑借其獨特的優(yōu)勢,Node.js的現(xiàn)在已經(jīng)在許多著名公司的產(chǎn)品中起到了關(guān)鍵作用。
在這篇文章中,我們不僅將討論這些優(yōu)勢是如何實現(xiàn)的,而且也會討論為什么你使用 Node.js 來替代一些經(jīng)典的Web應(yīng)用程序模型。
Node.js 是如何工作的?
Node.js 的主要思路是:使用非阻塞的,事件驅(qū)動的 I/O 操作來保持在處理跨平臺 (across distributed devices) 數(shù)據(jù)密集型實時應(yīng)用時的輕巧高效。這聽起來有點繞口。
它的真正含義是,Node.js 不是一個即將主導(dǎo)Web開發(fā)的世界的銀彈級的平臺。相反,它是一個滿足特別需求的平臺。你肯定不會希望使用 Node.js 去做 CPU密集型操作。事實上,使用它進(jìn)行繁重的計算等于摒棄 Node 幾乎所有的優(yōu)點。Node 真正的亮點在于建設(shè)高性能,高擴(kuò)展性的互聯(lián)網(wǎng)應(yīng)用——因為它能夠處理龐大的并且高吞吐量的并發(fā)連接。
它的工作原理是相當(dāng)有趣的。傳統(tǒng)的網(wǎng)絡(luò)服務(wù)技術(shù),是每個新增一個連接(請求)便生成一個新的線程,這個新的線程會占用系統(tǒng)內(nèi)存,最終會占掉所有的可 用內(nèi)存。而 Node.js 僅僅只運行在一個單線程中,使用非阻塞的異步 I/O 調(diào)用,所有連接都由該線程處理,在 libuv 的加分下,可以允許其支持?jǐn)?shù)萬并發(fā)連接(全部掛在該線程的事件循環(huán)中)。
做一個簡單的計算: 假設(shè)是普通的Web程序,新接入一個連接會占用 2M 的內(nèi)存,在有 8GB RAM的系統(tǒng)上運行時, 算上線程之間上下文切換的成本,并發(fā)連接的***理論值則為 4000 個。這是在傳統(tǒng) Web服務(wù)端技術(shù)下的處理情況。而 Node.js 則達(dá)到了約 1M 一個并發(fā)連接的拓展級別 (相關(guān)證明).
當(dāng)然,在所有客戶端的請求共享單一線程時也會有問題, 這也是一個編寫 Node.js 應(yīng)用的潛在缺陷. 首先, 大量的計算可能會使得 Node 的單線程暫時失去反應(yīng), 并導(dǎo)致所有的其他客戶端的請求一直阻塞, 直到計算結(jié)束才恢復(fù)正常。 其次,開發(fā)人員需要非常小心,不要讓一個 Exception 阻塞核心的事件循環(huán),因為這將導(dǎo)致 Node.js 實例的終止(實際上就是程序崩潰)。( 筆者注:如 PHP 中某個頁面掛掉是不會影響網(wǎng)站運行的,但是 Nodejs 是一個線程一個線程來處理所有的鏈接,所以不論是計算卡了或者是被異常阻塞了都可能會影響到其他所有的鏈接。解決方案在稍后討論。)
用來避免異常拋出時中斷進(jìn)程的方法是將異常使用回調(diào)傳遞出去(而不是拋出他們,就像在其他環(huán)境中一樣)。即使一些未處理的異常阻塞了程序,依舊有多 種應(yīng)對的解決方案,而且也有很多可用于監(jiān)視 Node 進(jìn)程來執(zhí)行必要的崩潰后恢復(fù)工作的策略和工具(雖然你將無法恢復(fù)用戶的 Session ),最常見的是使用 Forever 模塊,或者采用其他的外部系統(tǒng)工具如 upstart and monit。
NPM: The Node Package Manager
當(dāng)我們討論 Node.js 的時候,一個絕對不應(yīng)該忽略地方就是默認(rèn)內(nèi)置的模塊管理工具 —— NPM。 其靈感來源與 Ruby Gems(具有版本和依賴管理功能,可以通過在線資料庫便捷安裝可重用的組件的管理工具)。
一個完整的公用模塊列表可以在 NPM 的網(wǎng)站上找到(https:://npmjs.org/),或者通過使用與 Node.js 一同安裝的 NPM CLI 工具放問到。該模塊的生態(tài)系統(tǒng)向所有人開放,任何人都可以發(fā)布自己的模塊,所有的模塊都可以在 NPM 資料庫中找到。你可以在 http://howtonode.org/introduction-to-npm 頁面找到 NPM 的一個簡要介紹(有點舊,但依舊能看)。
目前非常流行的一些 NPM 模塊有:
- express – Express.js,是一個簡潔而靈活的 node.js Web應(yīng)用框架, 并且已經(jīng)是現(xiàn)在大多數(shù) Node.js 應(yīng)用的標(biāo)準(zhǔn)框架,你已經(jīng)可以在很多 Node.js 的書籍中看到它了。
- connect – Connect 是一個 Node.js 的 HTTP 服務(wù)拓展框架,提供一個高性能的“插件”集合,以中間件聞名,是 Express 的基礎(chǔ)部分之一。
- socket.io 和 sockjs – 目前服務(wù)端***的兩個 websocket 組件。
- Jade – 流行的模板引擎之一,并且是 Express.js 的默認(rèn)模板引擎。其靈感來源于 HAML。
- mongo 和 mongojs – 封裝了 MongoDB 的的各種 API,不過筆者平常工作用的是 mongoose 也很推薦。
- redis – Redis 的客戶端函數(shù)庫.
- coffee-script – CoffeeScript 編譯器,允許開發(fā)者使用 Coffee 來編寫他們的 Node.js 程序。
- underscore (lodash, lazy) – ***的 JavaScript 工具庫 , 用于 Node.js 的封裝包,以及兩個采取略有不同的實現(xiàn)方法來獲得更好性能的同行。
- forever – 可能是用來確保 node 腳本持續(xù)運行的***的工具。
還有很多好的模塊,這里就不一一列舉了(希望沒有冒犯到?jīng)]列舉的)。
Node.js 應(yīng)該用在什么地方
聊天
聊天是最典型的多用戶實時交互的應(yīng)用。從IRC開始,有許多開源或者不開源的協(xié)議都運行在非標(biāo)準(zhǔn)端口上,而現(xiàn)在,使用 Node.js 則可以解決這些問題——在標(biāo)準(zhǔn)的80端口運行 WebSockets。
聊天應(yīng)用程序是最能體現(xiàn) Node.js 優(yōu)點的例子:輕量級、高流量并且能良好的應(yīng)對跨平臺設(shè)備上運行密集型數(shù)據(jù)(雖然計算能力低)。同時,聊天也是一個非常值得學(xué)習(xí)的用例,因為它很簡單,并且涵蓋了目前為止一個典型的 Node.js 會用到的大部分解決方案。
讓我們試著來描繪它如何工作。
在最簡單的情況下,我們布置了一個聊天室在我們的網(wǎng)站上,用戶可以在上面發(fā)消息,當(dāng)然是一對多的形式。例如,假設(shè)總共有三個人連接到我們的網(wǎng)站上。
在服務(wù)端這邊, 我們有一個使用 Express.js 搭建的簡單站點,該站點實現(xiàn)了兩件事 1) 處理路徑為 ‘/’ 的GET請求時,下發(fā)包括一個留言板以及一個發(fā)送信息的 ‘發(fā)送’ 按鈕的頁面 2) 一個監(jiān)聽客戶端發(fā)送新消息的 websockets 服務(wù)。
在客戶端這邊,我們有一個 HTML 頁面,上面有個兩個 js 方法,一個是用于觸發(fā)事件的 “發(fā)送” 按鈕,這會把把輸入的消息通過 webscoket 發(fā)送,另一個方法是用 webscoket 在客戶端上監(jiān)聽服務(wù)端來的推送(例如,其他用戶發(fā)送的消息)。
當(dāng)有一個客戶端發(fā)送消息的時候,發(fā)生的事情是:
- 瀏覽器上,點擊發(fā)送按鈕觸發(fā)了 js 函數(shù),將輸入框中的文字通過 websocket 消息發(fā)送到服務(wù)器的 websocket 客戶端(頁面初始化加載的時候連接的)。
- 服務(wù)端的 websocket 組件收到 消息,然后通過廣播方法轉(zhuǎn)發(fā)到其他所有連接的客戶端。
- 通過頁面上運行的 websocket 客戶端組件,所有的客戶端都能收到這條推送的新消息。接著 js 處理函數(shù)可以把這個消息添加到文字框內(nèi)。
這是一個最簡單的例子。如果要更好的解決方案,你可以使用 Redis 數(shù)據(jù)庫做一個簡單的緩存。在一個更高級的解決方案中,你可能需要一個消息路由來專門處理消息隊列,并且需要一個更強(qiáng)健的發(fā)送機(jī)制,比如發(fā)送的時候覆蓋上暫 時離線的用戶或者為離線的注冊用戶存儲尚未接收的消息等等。但是不論你做了怎么樣的改進(jìn),Node.js 都將遵循一個基本原則:響應(yīng)事件,處理多個并發(fā)連接,并保持流動性的用戶體驗。
對象數(shù)據(jù)庫接口(API ON TOP OF AN OBJECT DB)
盡管,Node.js 確實非常擅長實時交互的應(yīng)用,同時它也十分適合通過對象數(shù)據(jù)庫(object DB)來查詢數(shù)據(jù)(如 MongoDB)。以 JSON 格式存儲的數(shù)據(jù)允許 Node.js 直接處理,不需要糾結(jié)數(shù)據(jù)轉(zhuǎn)換和匹配的問題。
舉個例子,如果你正在使用 Rails,你會將 JSON 數(shù)據(jù)轉(zhuǎn)成 二進(jìn)制的 model,當(dāng)數(shù)據(jù)再被 Backbone.js, Angular.js 或者 jQuery AJAX 之類的調(diào)用又要轉(zhuǎn)回 JSON。如果是 Nodejs 的話,你可以通過一個 REST API 簡單的導(dǎo)出 JSON 對象以供客戶端使用。另外,從數(shù)據(jù)庫讀寫時候如果使用的是 MongoDB 的話,你也不用擔(dān)心的 JSON 與任何數(shù)據(jù)之間的格式問題??傊?,你可以避免多元的數(shù)據(jù)轉(zhuǎn)換問題,不論是在客戶端、服務(wù)端還是數(shù)據(jù)庫。
隊列輸入
如果你正在接收一個高量并發(fā)的數(shù)據(jù),你的數(shù)據(jù)庫可能會成為你處理的瓶頸。正如上面的描述,Node.js 可以輕松的處理并發(fā)連接。 但是,由于數(shù)據(jù)庫操作是一個阻塞的操作(在這種情況下),這就是麻煩的地方。Node.js的解決方案是,在數(shù)據(jù)真正的寫入之前就承認(rèn)客戶端的數(shù)據(jù)是真實 的。
用這種方法,在高負(fù)載的時候系統(tǒng)繼續(xù)維持它的響應(yīng),這在當(dāng)客戶端不需要嚴(yán)格確認(rèn)一個數(shù)據(jù)是否成功的被寫入時特別有用。典型的例子包括:日志記錄或者用戶跟蹤數(shù)據(jù)(user-tracking data)的記錄,這會被分批處理并且在稍后才使用;同時也包括最終一致性(so, 常用于 NoSQL)可以接受,不需要立即反應(yīng)的操作(例如 Facebook 上更新點贊的數(shù)目)。
數(shù)據(jù)通過某些緩存或者消息隊列的基礎(chǔ)組件(例如 RabbitMQ, ZeroMQ)進(jìn)入隊列,并且通過一個獨立的數(shù)據(jù)庫批量寫入進(jìn)程來一一消化,或者通過一個更高性能的計算密集型后端服務(wù)來進(jìn)行處理。其他的語言/框架也可 以實現(xiàn)相似的操作,但在相同的配置下是達(dá)不到 nodejs 的高吞吐量與高并發(fā)。
簡單的說:使用 Node,你可以把數(shù)據(jù)庫操作扔到一邊并在稍后處理它們,假設(shè)他們成功了一樣繼續(xù)執(zhí)行下去。(筆者注:在開發(fā)中通常的情況通常是,種耗時的操作通過回調(diào)函數(shù)來異步處理,主線程繼續(xù)往下執(zhí)行)
數(shù)據(jù)流
在較為傳統(tǒng)的網(wǎng)絡(luò)平臺上,HTTP 的請求和響應(yīng)更像是孤立的事件;然而事實上,他們都是數(shù)據(jù)流。這一觀察結(jié)果在 Nodejs 上可以用來建立一些很酷的功能。因為數(shù)據(jù)通以流的形式接收,而我們可以在網(wǎng)站上在線處理正在上傳中的文件。這樣的話,就可以實現(xiàn)實時的音頻和視頻編碼,以及在不同數(shù)據(jù)源之間進(jìn)行代碼(代理見下一段)。
(筆者注:Node 有代替如 apache 這樣的 webserver 處理數(shù)據(jù),所以開發(fā)者可以直接收到客戶端一份一份上傳的數(shù)據(jù),并實時處理。上面這段話聽起來有點抽象,不過各位可以簡單的想象一下不需要開 YY 或者 QQ,打開網(wǎng)頁就能進(jìn)行語音視頻的功能。)
代理
Node.js 可以通過異步的方式處理大量的并發(fā)連接,所以很容易作為服務(wù)端的代理來使用。這在與不同響應(yīng)時間的不同服務(wù)之間進(jìn)行代理,或者是收集來自多個來源的數(shù)據(jù)時尤其有用。
舉個例子:考慮一個服務(wù)器端的應(yīng)用程序和第三方資源進(jìn)行通信以更新自不同來源的數(shù)據(jù),或者將服務(wù)端上的一些圖像和視頻資源存儲到第三方云服務(wù)。
雖然專用代理服務(wù)器確實存在,但是如果你還沒有專用的代理服務(wù)器,或者你需要一個本地開發(fā)的解決方案,那么使用 Node 來做代理可能是更好的選擇。關(guān)于這個解決方案,我的意思是指當(dāng)你在開發(fā)的時候,你可以使用Node.js的開發(fā)環(huán)境搭建一個服務(wù)來處理對資源和代理的請 求,而在生產(chǎn)環(huán)境下,你可以使用專用的代理服務(wù)(比如nginx,HAProxy等)來處理這些交互。
股票操盤手的儀表盤
讓我們繼續(xù)討論應(yīng)用程序這塊。實時網(wǎng)絡(luò)的解決方案可以很輕松的實現(xiàn)證券交易軟件——用于跟蹤股票的價格,執(zhí)行計算、做技術(shù)分析,同時生成報表。
使用一個實時的的基于網(wǎng)頁的解決方案,將會允許操盤手輕松的切換工作軟件以及工作地點。相信不久,我們或許會在 佛羅里達(dá)州、伊維薩島又或者是巴厘島的海灘上看到他們。
應(yīng)用監(jiān)聽儀盤表
另一種常見的用例中,使用 Node+Web+Socket 非常適合:跟蹤網(wǎng)站訪問者并且可視化實時它們之間的實時交互。 (如果你有興趣,可以去看看Hummingbird)
你可能需要采集用戶的實時狀態(tài), 或者甚至當(dāng)他們到達(dá)渠道中某個特定的點時, 打開一個交流頻道, 通過有針對性的互動介紹移動到下一個階段. (如果你感興趣的話,推薦你看看 CANDDi)
想象一下,如果你知道你的訪客的實時操作,并能夠形象化地看到他們的交互,這將對你的業(yè)務(wù)帶來多大的提升。隨著實時的、雙向 socket 通信的 Node.js ,現(xiàn)在你可以做到了。
系統(tǒng)監(jiān)控儀表
現(xiàn)在,讓我們看看事情的基礎(chǔ)設(shè)施方面。想象一下,比如,希望為其用戶提供服務(wù)監(jiān)控頁面(例如,GitHub上的狀態(tài)頁)的 SaaS 運營商 。通過 Node.js 的事件循環(huán),我們可以創(chuàng)建一個基于 Web 的功能強(qiáng)大的儀表板,以異步方式檢查服務(wù)狀態(tài)并且使用的 WebSockets 將數(shù)據(jù)推送到客戶端。
內(nèi)部(公司內(nèi)部)和公共服務(wù)的狀態(tài)都可以使用該項技術(shù)實現(xiàn)實時的上報。讓我們把這一想法延伸的遠(yuǎn)一點,試著想象一個電信運營商中網(wǎng)絡(luò)運營中心(NOC)的監(jiān)控應(yīng)用,云/網(wǎng)絡(luò)/服務(wù)器運營商,或者一些金融機(jī)構(gòu),全都運行在這個由 Node.js 和 WebSocket 組成的應(yīng)用上,而不是 Java 和/或 Java Applet。
注意:不要嘗試使用 Node 打造硬實時系統(tǒng)(即,響應(yīng)時間要求一致的系統(tǒng))。 Erlang是可能是該類應(yīng)用程序的更好的選擇。
什么地方可以使用 Node.js
服務(wù)端 WEB 應(yīng)用
通過 Node.js 使用 Express.js 也可以用來創(chuàng)建服務(wù)端上的典型的網(wǎng)頁應(yīng)用。然而,雖然有可能,使用 Node.js 來進(jìn)行請求+響應(yīng)的形式來呈現(xiàn) HTML 并不是最典型的用例。有人贊成也有人反對這一做法。這里有一些看法以供參考:
優(yōu)點:
- 如果你不需要進(jìn)行 CPU密集型計算,你可以從頭到尾甚至是數(shù)據(jù)庫(比如 MongoDB)都使用 Javascript 來開發(fā)。這顯著地減輕了開發(fā)工序(包括成本)。
- 對于一個使用 Node.js 作為服務(wù)端的單頁應(yīng)用或者 websocket 應(yīng)用,爬蟲可以收到一個完全 HTML 呈現(xiàn)的響應(yīng),這是更為SEO友好的。
缺點:
- 任何CPU密集型的計算都將阻礙 Node.js 的反應(yīng),所以使用多線程的平臺是一個更好的方法?;蛘?,您也可以嘗試向外擴(kuò)展的計算[*]。
- Node.js 使用關(guān)系型數(shù)據(jù)庫依舊十分痛苦(詳細(xì)見下方)。拜托了,如果你想執(zhí)行關(guān)系型數(shù)據(jù)操作,請考慮別的環(huán)境:Rails, Django 甚至 ASP.NET MVC 。。。。
【*】另一種解決方案是,為這些CPU密集型的計算建立一個高度可擴(kuò)展的MQ支持的環(huán)境與后端處理,以保持 Node 作為一個前臺專員來異步處理客戶端請求。
Node.js 不應(yīng)該在什么地方使用
使用關(guān)系型數(shù)據(jù)庫的服務(wù)端 WEB 應(yīng)用
對比 Node.js 上的 Express.js 和 Ruby on Rails,當(dāng)你使用關(guān)系型數(shù)據(jù)庫的時候請毫不猶豫的選擇后者。
Node.js 的關(guān)系數(shù)據(jù)庫工具仍處于早期階段,目前還沒有成熟到讓人能夠愉快地使用它。而與此同時,Rails天生自帶了數(shù)據(jù)訪問組件,連同DB schema遷移的支持工具和一些Gems(一語雙關(guān),一指這些如同珍寶的工具,二指ruby的gems程序包)。Rails和它的搭檔框架們擁有非常成 熟且被證明了的活動記錄(Active Record)或數(shù)據(jù)映射(Data Mapper)的數(shù)據(jù)訪問層的實現(xiàn),而這些是當(dāng)你在使用純JavaScript來復(fù)制這些應(yīng)用的時候會非常想要使用的東西。
不過,如果你真的傾向于全部使用 JS(并且做好可能抓狂的準(zhǔn)備),那么請繼續(xù)關(guān)注 Sequelize 和 Node ORM2 ,雖然這兩者仍然不成熟的,但他們最終會迎頭趕上。
[*] 使用 Node 光是作為前端而 Rails 做后端來連接關(guān)系型數(shù)據(jù)庫,這是完全有可能也并不少見的。(筆者注:國外有種說法,PHP這一類程序員也可以算作是前端)
繁重的服務(wù)端的計算和處理
當(dāng)涉及到大量的計算,Node.js 就不是***的解決方案。你肯定不希望使用 Node.js 建立一個斐波那契數(shù)的計算服務(wù)。一般情況下,任何 CPU密集型操作 會削弱掉 Node通過事件驅(qū)動, 異步 I/O 模型等等帶來的在吞吐量上的優(yōu)勢,因為當(dāng)線程被非異步的高計算量占用時任何傳入的請求將被阻塞。
正如前面所說,Node.js 是單線程的,只使用一個單一的CPU核心。至于,涉及到服務(wù)器上多核并發(fā)處理,Node 的核心團(tuán)隊已經(jīng)使用 cluster 模塊的形式在這一方面做了一些工作 (參考:http://nodejs.org/api/cluster.html)。當(dāng)然,您也可以很容易的通過 nginx 的反向代理運行多個 Node.js 的服務(wù)器實例來避免單一線程阻塞的問題。
關(guān)于集群(clustering) ,你應(yīng)該將所有繁重的計算轉(zhuǎn)移到更合適的語言寫的后臺進(jìn)程來處理,同時讓他們通過像 RabbitMQ 那樣通過消息隊列服務(wù)器來進(jìn)行通信。
即使你的后臺處理可能最初運行在同一臺服務(wù)器上時看不出什么優(yōu)點,但是這樣的做法具有非常高的可擴(kuò)展性的潛力。這些后臺處理服務(wù)可以容易地分割出去,作為單獨的 worker 服務(wù)器,而不需要配置入口 web服務(wù)器的負(fù)載。
當(dāng)然,你也可以在其他語言平臺上用同樣的方法,但使用 Node.js 你可以得到很高的吞吐量,每個請求都作為一個小任務(wù)非常迅速和高效地處理,這一點我們已經(jīng)討論過了。
結(jié)論
我們已經(jīng)從理論到實踐討論過 Node.js 了,從它的目標(biāo)和野心,到其優(yōu)點和缺點。在 Node.js 的開發(fā)中99%的問題是由誤用阻塞操作而造成的。
請記?。篘ode.js 從來不是用于解決大規(guī)模計算問題而創(chuàng)建的。它的出現(xiàn)是為了解決大規(guī)模I/O 的問題,并且在這一點上做的非常好。
綜上,如果你項目需求中不包含CPU密集型操作,也不需要訪問任何阻塞的資源,那么你就可以利用的 Node.js 的優(yōu)點,盡情的享受快速、可擴(kuò)展的網(wǎng)絡(luò)應(yīng)用。
原文鏈接:http://www.toptal.com/nodejs/why-the-hell-would-i-use-node-js