2012-11-12 14 views
9

假設我正在構建一個三層網站,在後端使用Mongo DB,並在瀏覽器中使用一些非常輕量級的JavaScript(比如,只需在窗體上進行驗證,也許可以使用一些特殊的控件來引發一些AJAX請求)。我需要爲「中間」層選擇一種技術(我們可以將其分成多個子層,但這裏的細節並不是重點,只是整體技術的選擇),我想在這裏關閉一些原始數據從數據庫中出來,並將其渲染爲一些我推送給瀏覽器的HTML。一個相當典型的瘦客戶端Web架構。Node.js是否應該用於密集處理?

我的安全選擇是在Java中實現這個中間層,使用像Jongo這樣的庫來與Mongo DB交談,也許Jackson會編組/解組JSON,以便在他們發出AJAX請求時與我的控件進行交談。還有一些用於在服務器上呈現我的HTML的模板框架。

  • 我喜歡的JavaScript(好的部分:

    不過,我真的拋出這一切窗外,並使用Node.js的這個中間層,由於以下原因的想法很感興趣),並且假設這個應用程序的業務邏輯比Java更具表現力。

  • 它的JavaScript無處不在。在堆棧上的任何位置工作時,無需在語言之間進行切換,實際上也可以在面向對象和功能範例之間切換。層之間沒有翻譯管道,JSON在本地無處不在。

  • 我可以在客戶端和服務器上重新使用驗證邏輯。

  • 如果將來我決定在瀏覽器中執行HTML渲染客戶端,我可以重用現有的模板,像Backbone一樣,只需很少的重構/重測工作。

如果您在這一點上並且喜歡Node,以上所有內容都顯得很明顯。所以我應該選擇節點吧?

但是......這就是對我而言的原因:衆所周知,Node基於單線程異步I/O Web服務器模型。這對於我的數據服務請求方面的可伸縮性和性能來說非常棒,但我的業務邏輯又如何呢?那麼我的模板渲染呢?這些東西不會對單線程上的所有請求造成巨大的瓶頸嗎?

兩個顯而易見的解決方案浮現在腦海中,但他們都沒有坐在右:

  1. 保持「阻塞」業務邏輯在那裏,只是使用節點實例的羣集和負載均衡,服務請求真正平行。好,那麼爲什麼Node不是多線程的呢?或者,這是否總是這樣的想法:保持簡單愚蠢,並避免在基本情況下出現多線程複雜性的可能性,如果需要多核處理能力,程序員可以在此基礎上做額外的安裝工作?

  2. 保留單個節點實例,並通過調用某些其他多線程應用服務器上運行的業務邏輯的某個Java實現來保持它爲非阻塞狀態。好的,這個選項完全無效了我列出的使用Node的每個專業人員(實際上它比僅使用Java增加了複雜性),除了CRUD請求到DB的性能和可伸縮性方面可能的增益之外。

這最終使我對我問題的要點 - 我錯過了節點難題的一些巨大的重要的一塊,有我剛拿到手的事實完全錯誤的,或者是節點只是不適合在搗鼓業務邏輯服務器?換句話說,Node是否比坐在I/O上的其他一些實現更適合用於坐在數據庫上並以更高性能和更可伸縮的方式服務多個CRUD請求?你必須在下面的某個層次或甚至客戶端執行所有業務邏輯才能保持合理的性能和可伸縮性級別?考慮到所有關於Node的嗡嗡聲,我寧願希望它帶來更多的表現。我很樂意相信!

+0

節點是單線程的原因是所有當前化身(不是計劃或「邊緣化身」)中的JavaScript都是單線程的。這條規則有一些例外,例如客戶端的webworkers,但即使如此,您的線程模型也不同於您在其他語言中可能使用的模式。 – Matt

+0

好點,我並不是真正意義上的真正的多線程,因爲在線程可以共享數據,我的意思是類似於webworkers - 只是一個請求被並行服務的方式,沒有彼此的知識,出於盒子。這顯然可以通過對節點服務器進行集羣來實現 - 我的問題是您不希望這樣做的用例是什麼?單節點Web服務器有什麼實際用途? – davnicwil

回答

7

在任何給定的系統有可用ñ的CPU(1-64,或任何ñ恰好是)。在任何CPU密集型應用程序中,您將被卡住的吞吐量爲N cpus。有沒有不可思議的方式來增加超過N線程/進程/不管。要麼你的代碼更高效,要麼你需要更多的CPU。更多的線程無濟於事。

其中一個關於多CPU性能的鮮爲人知的事實是,如果您需要同時運行N + 1 CPU密集型操作,則每個CPU的吞吐量會降低很多。在放棄CPU之前,CPU密集型進程往往會持續很長一段時間,而其他任務相當糟糕。在大多數情況下,它阻止了I/O,伴隨而來的任務切換使得現代操作系統的多任務處理工作以及它的確如此。如果我們每天的更多常見任務都是CPU限制的,那麼我們會發現我們的機器中需要更多的CPU,而不是我們目前的CPU。

Node.js給服務器方效率帶來的好處是每個線程的徹底使用。理想情況下,最終的任務切換更少。這是不是一個巨大的,不過話說ň線程處理ñ* C連接異步將會有超過ñ* C阻塞在同一個數量的CPU運行的線程性能上的優勢。但是CPU的底線依然如此:如果你有超過N實際的CPU工作要完成,你會感到有些痛苦。

上次我看了看Node.js的API有推出服務器用一個監聽器加上每個CPU有一個工作線程的方法。如果你能做到這一點,我會傾向於與Node.js一起提供幾個注意事項:

  • Javascript-everywhere方法爲您帶來一些簡單性。對於複雜的事情,我會擔心異步編程風格會讓事情變得更加困難而不是簡單。
  • 模板加工等CPU密集型任務不是明顯在Node.js的比你的其他語言/平臺選擇慢。
  • 數據庫驅動程序是可靠的。

有一個缺點,我可以看到:

  • 如果一個線程崩潰,你失去所有的連接正由線程服務。

最後,請記住,程序員的時間通常比服務器或帶寬更昂貴。

+0

很棒的回答。所以我猜想,真正歸結爲使用更少的線程(甚至可能是單個線程)通過消除I/O上的阻塞來監聽和服務請求。這確實很有意義。感謝您指出潛在的工作線程使用 - 這正是我所說的,也就是說,當需要完成一些實際的處理時(例如從DB讀取的回調)時,可以將其轉移到工作線程池,而保持請求偵聽器線程正在旋轉。當然你所做的任何工作最終都受服務器的cpus和V8的速度限制:-) – davnicwil

相關問題