使用node.js的可扩展推送应用程序

时间:2011-12-28 20:21:29

标签: node.js mongodb nosql

我正在考虑编写几个与聊天几乎相同的Web应用程序。我希望他们能够轻松扩展。

我对node.js有点了解,我理解它如何帮助设计推送应用程序,但在考虑让它们在多个服务器上运行时我遇到了一些困难。

以下是我可以想到的一个大型聊天应用程序的设计:

1 - 服务器具有状态,它们保持连接打开,客户端可以将新消息推送给它们。在这种情况下,我们受到一台服务器的物理内存的限制,因此如果每个房间的用户太多,我们就无法线性扩展。

2 - 服务器没有状态,它们请求分布式数据库响应客户端请求。在此方案中,客户端轮询服务器。我们可以线性扩展,但吞吐量会降低,消息不会立即传递,并且在缩放时轮询已被证明是一种不好的做法。

3 - 1和2的混合。服务器保持其客户端的连接打开并轮询分布式数据库。应用程序编写起来比较复杂,我们仍然使用轮询。类似客户端的请求(同一房间的客户端)仅被分组为由服务器完成的单个客户端。代码变得不必要复杂,并且在我们每个房间有很多房间和几个用户的情况下它不会扩展。

4 - 服务器没有状态,数据库集群使用事件通知每个已注册的服务器有关新消息的信息。这是我想要的解决方案,但我还没有听说过任何具有此功能的数据库。 (有些人在这里讨论mongodb的这个功能:https://jira.mongodb.org/browse/SERVER-124

那么为什么今天第四种解决方案没有那么多用呢?

在这种情况下,人们通常如何设计应用程序?

2 个答案:

答案 0 :(得分:4)

由于您需要推送应用程序,因此可能会将Socket.IO与RedisStore一起使用。

通过使用此组合,所有连接的数据都保存在Redis(内存数据库)中,因此您可以在进程外扩展。 Redis的另一个用途是pub-sub。

这个想法是在需要推送某个东西时触发一个事件,然后使用Socket.io向浏览器发送一条消息。如果您想收听数据库更改,可能最好使用CouchDB with it's _changes feature

资源:

https://github.com/dshaw/talks/tree/master/2011-10-jsclub/sample-app
http://www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html
How to reuse redis connection in socket.io?

答案 1 :(得分:1)

您可能希望挂钩MongoDB复制,而不是案例4的触发器。

假设你有一个replica set(你不会运行单个mongod,不是吗?)。

每次更改都会写入主要内容的oplog,然后会复制到次要内容。

您可以使用tailable cursors从oplog中有效地提取新更新。注意,这仍然是拉动,而不是推动。

然后你的node.js会将这些事件推送给客户。