2016-03-24 106 views
0

我有一個節點羣集其中主站響應http請求。 服務器還偵聽websocket連接(通過socket.io)。客戶端通過所述websocket連接到服務器。現在客戶端在各種遊戲之間進行選擇(每個節點進程處理一個遊戲)。使用websockets進行節點羣集

的問題,我已經有以下幾種:

  • 我應該打開每個節點工藝的新連接?如何告訴客戶端他應該連接到確切的節點進程X? (因爲服務器可能會處理傳入的連接請求)
  • 是否可以將套接字傳遞給節點進程,以便不需要打開新的連接?
  • 如果我只使用一個連接(在主進程中)並將用戶消息傳遞給各個節點進程並將進程消息傳回給用戶,那麼有什麼缺點? (我覺得它的成本大量的CPU發送進程間消息時複製相當大的物體)

回答

2

是否有可能將套接字傳遞到一個節點的過程,所以沒有 需要打開一個新的連接?

您可以按照node.js doc here中所述向另一個節點進程發送純TCP套接字。其基本思路是這樣的:

const child = require('child_process').fork('child.js'); 
child.send('socket', socket); 

然後,在child.js,你有這樣的:

process.on('message', (m, socket) => { 
    if (m === 'socket') { 
    // you have a socket here 
    } 
}); 

的「窩」消息標識符可以是您選擇的任何消息的名字 - 它不是特別。 node.js的代碼是當您使用child.send()並且您發送的數據被識別爲套接字時,它使用平臺特定的進程間通信與其他進程共享該套接字。

但是,我相信這隻適用於尚未建立TCP狀態以外的任何本地狀態的普通套接字。我自己並沒有嘗試使用建立的webSocket連接,但我認爲它不起作用,因爲一旦webSocket具有更高級別的狀態而不僅僅是TCP套接字(例如加密密鑰),就會出現問題,因爲操作系統不會自動將該狀態轉移到新流程。

我應該爲每個節點進程打開一個新的連接嗎?如何告訴 客戶端他應該連接到確切的節點進程X? (因爲 服務器可能處理其對傳入的連接請求)

這可能是獲得新的過程socket.io連接的最簡單的方法。如果你確定你的新進程正在監聽一個唯一的端口號並且它支持CORS,那麼你可以在主進程和客戶端之間取得你已經擁有的socket.io連接,並向它上面的客戶端發送消息告訴客戶端在哪裏重新連接(什麼端口號)。然後,客戶端可以包含代碼來偵聽該消息並建立到新目的地的連接。

什麼缺點,如果我只使用一個連接(在主 處理),並通過用戶的消息到相應的節點處理 並且處理消息返回給用戶? (我覺得它的成本CPU的很多 的 進程之間發送消息時複製相當大的物體)

的缺點是,你揣。你的主進程只需要花費CPU能量作爲中間人轉發數據包的兩種方式。這項額外的工作對你來說是否重要取決於上下文,並且必須通過測量來確定。


這是我發現的更多信息。看來,如果到達主服務器的傳入socket.io連接在連接建立其初始socket.io狀態之前立即發送給羣集子節點,那麼這個概念也可以用於socket.io連接。

這裏的an article on sending a connection to another server帶有實現代碼。這似乎是在連接時立即完成的,因此它應該適用於指向特定羣集的傳入socket.io連接。這裏的想法是,對特定羣集進程進行粘性分配,並且到達主機的任何類型的所有傳入連接都會在它們建立任何狀態之前立即轉移到羣集子進程。

+0

[文檔](https://nodejs.org/api/child_process.html#child_process_child_process.html#child_process_child_send_message_sendhandle_options_callback)指出整個服務器可以通過'child_process.send'發送。我不確定我們是否可以將WebSocketServer發送到其他羣集。此功能可能有助於避免重新連接整個連接與崩潰。 – Lewis

+0

@Tresdin - 你並沒有真的發送一個「整個服務器」。您正在發送偵聽傳入連接的套接字,以便其他進程可以偵聽這些傳入連接。在典型的安裝中,通常沒有單獨的WebSocketServer,因爲傳入的WebSocket連接通常與常規Web服務器HTTP連接共享相同的端口(並因此與服務器共享)。並且,請記住,所有的socket.io連接都以HTTP連接的形式開始,然後通過升級過程協商將協議更改爲webSocket協議。 – jfriend00

+0

@Tresdin - 但是,是的,您可以將偵聽服務器套接字發送到另一個進程。 – jfriend00