SocketIO缩放架构和大型机房要求

我们在一个大型聊天应用程序上使用socketIO。

在某些情况下,我们希望向所有其他用户发送“状态”(用户可用性)。

io.in('room1').emit('availability:update', {userid='xxx', isAvailable: false}); 

room1可能包含很多用户(最多500个)。 当许多可用性更新被触发时,我们观察到NodeJS负载的显着提升。

这个想法是使用与Socket IO类似的Redis存储。 让Web浏览器客户端连接到不同的NodeJS服务器。

当我们想要发射到一个房间时,我们使用Redis PubSub ZeroMQ甚至RabbitMQ将“发射到房间1”的有效载荷分配给所有其他的NodeJS进程。 每个进程都会自己调用他自己的io.in('room1').emit

对这种设置的关注之一是进程间的通信可能变得相当繁忙,我想知道它是否会在未来成为一个问题。

这是我想到的架构。

在这里输入图像描述

关于可用的用户function,我认为有两种select,你可以创build一个“队列用户”,从连接用户的内容“公共数据”,或者你可以使用交换绑定信息连接的显示用户。 如果你使用“用户队列”,这对于每个“房间”将是相同的,当用户外出时,可以更新它,从队列中“popup”它的状态消息(尽pipe你必须“重新组织”所有队列消息为了它)。

尽pipe如此,我认为RabbitMQ是为asynchronous通信而devise的,并不是很有用,近似值有用户注册或不注册。 我认为对于那些不知道用户什么时候会收到这个消息以及它的“真实可用性”(“fire and forget architectures”)的应用程序来说更好。 ZeroMQ需要从零开始做更多的工作,但是你可以用更好的性能来实现更具体的事情。

从RabbitMQ站点发布/订阅的例子可能是一个很好的一点,开始一个新的devise像你的一个消息,它发送给几个用户在同一时间。 总之,我将为用户创build两个队列(接收和发送队列消息),并且使用交换绑定的信息来控制每个房间中的用户的每个“聊天室”使用特定的交换。 总是你有两个队列的用户,你创build交换绑定到一个或多个“聊天室”。

我希望这个答案可能对你有用,抱歉我的英文不好。

你可以批量更改,只分发他们每5秒左右? 换句话说,在每个节点服务器上,只需在所有用户的当前状态(例如“连接”,“空闲”等等)的每X秒内进行一次“快照”,然后将其发送到群集中的其他相关服务器。

然后,每个服务器每隔5秒钟执行一次相同的消息,只将用户状态的更改作为一个批处理对象数组发送给所有连接的客户端。

现在,我很惊讶你试图发送有关每个用户的信息作为一个包。 批量似乎可以很好地解决您的问题,因为它也可以更好地使用通常通过路由器和交换机传输的标准数据包大小。

这是跨多个Socket.io进程共享数据的常用方法。 到目前为止,你已经完成了一个单独的进程和一个线程。 我可以拙劣地假设你可以select任何提到的技术来交stream共享数据而不会造成任何性能问题。

如果你需要的只是IPC,你也许可以看看Faye 。 但是,如果您需要保留一些数据,则可以使用与CPU一样多的Redis主数据库来启动Redis群集,尽pipe这会为Pub / Sub添加较小的networking噪声。

您正在寻找这个库: https : //github.com/automattic/socket.io-redis

哪个可以用这个发射器: https : //github.com/Automattic/socket.io-emitter