使用websockets进行节点集群

时间:2016-03-24 15:47:46

标签: node.js sockets websocket socket.io node-cluster

我有一个节点群集,其中主服务器响应http请求。 服务器还侦听websocket连接(通过 socket.io )。客户端通过所述websocket连接到服务器。现在客户端在各种游戏之间进行选择(每个节点进程处理一个游戏)。

我的问题如下:

  • 我应该为每个节点进程打开一个新连接吗?如何告诉客户端他应该连接到确切的节点进程X? (因为服务器可能会处理其上的传入连接请求)
  • 是否可以将套接字传递给节点进程,以便不需要打开新连接?
  • 如果我只使用一个连接(在主进程中)并将用户消息传递给相应的节点进程并将进程消息传回给用户,有什么缺点? (我觉得在进程之间发送消息时复制相当大的对象需要花费大量的CPU)

1 个答案:

答案 0 :(得分: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
  }
});

'socket'消息标识符可以是您选择的任何消息名称 - 它并不特殊。 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连接。这里的想法是,对特定集群进程进行粘性分配,到达主服务器的任何类型的所有传入连接都会在建立任何状态之前立即转移到集群子进程。