我有一个node.js tcp服务器,用作iPhone聊天客户端的后端。由于我的实现包括私人群聊,我在内存中存储用户列表及其所属的聊天室,以便适当地路由消息。这一切都很好,假设我的聊天服务器总是在一台机器上,但是当我需要横向扩展时,我需要一种向连接到不同服务器的客户端广播消息的好方法。我不想开始在节点服务器之间进行进程间通信,而是希望与redis共享状态。
我有一些想法,但我想知道是否有人有一个很好的解决方案吗?这里要清楚的是一个例子:
用户1连接到X房间的服务器1,用户2连接到X房间的服务器2.用户1发送消息,我需要将其传递给用户2,但由于我使用的是内存数据结构服务器不共享状态。我希望我的节点服务器尽可能保持愚蠢,这样我就可以添加/删除我的系统需求。
谢谢:)
答案 0 :(得分:3)
您可以使用跨越流程的消息传递层(使用类似pub / sub的东西):
Message Queue
-------------------------------------------------------------------------------
| |
ServerA ServerB
------- -------
Room 1: User1, User2 Room 1: User3, User5
Room 2: User4, User7, User11 Room 2: User6, User8
Room 3: User9, User13 Room 3: User10, User12, User14
假设User1发送聊天消息。 ServerA在消息队列上发送一条消息,说“房间1中的User1说了些什么”(以及他们说的话)。每个其他服务器进程都会侦听此类事件,因此,在此示例中,ServerB将看到它需要将消息从User1分发到其拥有 Room 1中的所有用户。您可以扩展到许多以这种方式处理 - 每个新进程只需要确保它们在队列中侦听适当的消息。
如果您已经在使用Redis,Redis已经pub/sub functionality可以使用此功能。另外,还有其他第三方工具可用于此类事务,例如ZeroMQ;另见this question。
答案 1 :(得分:0)
Redis应该在不久的将来内置集群支持,同时您可以使用一致的散列算法在多个服务器之间均匀分配密钥。有人在那里有一个node.js的散列模块,它专门用于为node.js的redis集群模块实现一致的散列。您可能希望关闭“房间”名称以确保房间的所有数据点都在同一主机上。使用这种类型的设置,服务器使用的所有逻辑都保留在客户端上,因此您的redis群集基本上可以保持不变,您可以轻松添加或删除主机。
更新
我发现了我正在讨论的redis的一致哈希实现,它当然提供了代码,并且还以易于理解的方式解释了分片。
http://ngchi.wordpress.com/2010/08/23/towards-auto-sharding-in-your-node-js-app/