2012-11-13 20 views
6

Supose我需要實現一個Web應用程序,該應用程序將具有大量的併發用戶。我決定使用node.js,因爲它擴展得非常好,它有很好的性能,開源社區等等。然後,爲了避免瓶頸,因爲我可以在同一個事件循環中擁有超過一百萬用戶,我決定使用一個簇進程利用多核CPU。此外,我有3臺機器(main + 2),因爲我需要用Cassandra處理大數據。太棒了,這意味着我有3 * n node.js進程,其中n是cpu的核心數(機器是相同的)。如何設計分佈式node.js web服務器

好了,然後我開始研究,我有以下模式結束:

  • Nginx的偵聽端口80和僅用於提供靜態內容(IMG,CSS,JS等)。
    將動態流量轉發到haproxy。我知道如何配置nginx,但我仍然需要看看haproxy,所以我會說haproxy正在偵聽端口4000. Nginx和haproxy安裝在主機(入口點)。
  • 3臺機器之間的Haproxy負載平衡。它的流量轉發到端口4001,也就是Node.js的進程正在聽4001
  • 每node.js中具有n個過程的集羣聽4001

如果我是正確的單http請求將被轉發到單個node.js進程。

創建會話是很正常的,對吧?會話只是一個映射,而這個映射是一個Object,而這個Object存在於一個node.js過程中。 Haproxy將配置循環調度程序,因此可以將同一用戶轉發到不同的node.js進程。我如何跨所有node.js進程共享相同的會話對象?我如何共享全局對象(這包括在同一臺計算機(node.js集羣)和整個網絡中)? 我應該如何設計一個帶有node.js的分佈式Web應用程序?有沒有任何模塊可以簡化同步任務?

+1

haproxy有多種處理粘性會話的方法,http:// stacko verflow.com/questions/6498030/load-balancing-haproxy-or-other-sticky-sessions。對於全局對象,請使用redis或其他東西。 – numbers1311407

+0

類似於http://stackoverflow.com/questions/5398209/scaling-node-js-across-multiple-cores-servers還只有3個服務器。 –

回答

1

您可以使用memcache或redis來存儲會話對象。在重新啓動節點進程的情況下非常有用(如果會話數據存儲在進程的內存中將會丟失)。

此外,你可以檢查pm2功能列表,也許其中一些將對你有用。

構建微服務架構將具有良好的可擴展性。

1

正如Ivan指出的那樣,您將會話對象存儲在memcache或redis甚至Couchbase(memcache存儲桶)中。我還想補充一點,如果你想構建一個可擴展的系統,你的目標應該是以一種可以線性擴展的方式構建系統,以便根據需求提高吞吐量。我的意思是,您應該能夠在任何時候(最好是在高峯時段)將更多的主機添加到基礎架構中的不同層以處理需求。

因此,您必須非常小心您選擇的技術和您在開發過程中做出的設計決策。

Supose我需要實現一個Web應用程序,它將擁有大量的併發用戶。

我想補充的另一件事,如果你不能測量它,你無法管理它。一個好的開始會定義​​什麼「大量的併發用戶」對你意味着什麼?是Facebook還是WhatsApp類型的音量/併發性?通過與你的利益相關者(如果有的話)合作,首先定義這些,然後你就可以開始做出設計決策和挑選技術。

建立一個可擴展的系統時,一個好的試金石測試是問自己,「是否有單點故障?如果是,那麼你的系統不會擴展。

0

正如另一位用戶所建議的;使用Redis是完全可以接受的解決方案。

它的低谷在於使用服務來存儲會話對象,並讓中間件處理所有其他事情。如前所述,它在節點進程重啓,崩潰等情況下非常有用。將會話數據存儲在節點進程中會帶來風險。使用微服務(如Redis)的好處之一就是減少了這些風險。

假設您爲中間件使用Express,則可以使用一種稱爲Session store的東西。有很多模塊可以利用這個功能。

其中一個模塊是connect-redis

安裝是一件輕而易舉的事像往常一樣:

npm install connect-redis express-session 


那麼你可以使用它像這樣:

var session = require('express-session') 
var RedisStore = require('connect-redis')(session) 

app.use(session({ 
    store: new RedisStore(options), 
    secret: 'keyboard cat' 
})) 

現在,你用你的會話對象,就像你通常那樣。 (req.session


實例:

要設置的會話信息(從表單POST,例如):

req.session.email = req.body.email 


要檢索的會話信息:

console.log(req.session.email)