2016-03-24 60 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