我们在大型聊天应用程序上使用socketIO。
在某些方面,我们希望向所有其他用户发送“存在”(用户可用性)。
io.in('room1').emit('availability:update',{userid='xxx',isAvailable: false});
room1可能包含很多用户(最多500个)。当触发许多可用性更新时,我们观察到NodeJS负载显着升高。
这个想法是使用类似于使用Socket IO的redis存储的东西。让Web浏览器客户端连接到不同的NodeJS服务器。
当我们要发射到一个房间时,我们使用Redis PubSub ZeroMQ或甚至RabbitMQ来持久化,将“emit to room1”有效负载发送到所有其他NodeJS进程。每个进程本身都会调用自己的io.in(‘room1’),发射到他的连接用户的子集。
这个设置的关注之一是,进程间通信可能变得很忙,我想知道它是否会在将来成为一个问题。
这是我想到的架构。
解决方法
关于可用的用户功能,我认为有两种选择,可以创建一个“队列用户”,其中将连接的用户的内容“公共数据”,或者可以使用交换绑定信息连接显示用户。如果您使用“用户队列”,则每个“房间”都相同,您可以在用户出门时将其状态消息从队列中弹出(尽管您必须“重组”所有队列消息为了它)。
不过,我认为RabbitMQ是专为异步通信而设计的,它不是非常有用的近似,有一个用户的存在或不存在的注册。我认为对于您不知道用户何时会收到消息的应用程序及其“实际可用性”(“启动和忘记体系结构”)更为适用。 ZeroMQ需要从零开始的更多工作,但您可以实现更具体的针对您的情况的更好的性能。
来自RabbitMQ网站的发布/订阅示例可能是开始像您这样的新设计的好点,其中一个消息同时发送给多个用户。总而言之,我将为用户(接收和发送队列消息)创建两个队列,并且将使用交换绑定信息来控制每个房间中的每个房间的每个“房间聊天”的特定交换。始终你有两个队列为用户,你创建交换绑定到一个或多个“聊天室”。
我希望这个答案对你有用,对不起我的坏英语。