首先,让我们澄清一下 socket.io 和 RethinkDB 变更源之间的关系。 Socket.io 旨在用于客户端(浏览器)和服务器(Node.js)之间的实时通信。 RethinkDB changfeeds 是您的服务器 (Node.js) 侦听数据库中的更改的方式。客户端无法直接与RethinkDB通信。
实时应用程序的一个非常典型的架构是让 RethinkDB 变更源订阅数据库中的更改,然后使用 socket.io 将这些更改传递给客户端。客户端通常还会发出可以写入数据库的消息,具体取决于您的应用程序逻辑。
是的,您可以通过 socket.io 发出所有消息,然后将所有消息传递给所有客户端,然后将这些消息写入数据库以进行持久化。这确实更快,但这种方法有很多缺点。
1. 数据库作为单一事实来源
最容易发现的问题如下:
- 如果您的应用程序无法向
数据库?
- 如果您尝试插入数据库的数据无效或重复,会发生什么情况?您编写应用程序逻辑来处理这个问题吗?
- 如果 Node.js 服务器在发送之前发生故障会发生什么
写查询?
这些只是一些简单的示例,在这些示例中,由于您的架构,您将丢失或不同步数据。重申一下,您将丢失数据,因为您的主要事实来源位于内存中。您的 Node.js 应用程序和数据库中的数据也可能存在差异。
关键是数据库应该始终是您的唯一事实来源,并且您应该仅在数据写入磁盘时确认数据。我不确定其他人晚上怎么能睡得着觉。
2. 高级查询
如果您只是通过 socket.io 将所有客户端的所有新消息传递给所有客户端,那么现在您的客户端中必须有一些相当复杂的逻辑,以便过滤掉所有真正重要的数据。考虑到您正在通过网络传递大量客户端实际上不会使用的无用数据。
另一种方法是编写一个发布/订阅系统,您可以在其中订阅某些频道(或类似的内容),以便过滤掉对客户端真正重要的数据。
RethinkDB 通过提供自己的查询语言来解决这个问题,您可以将其附加到变更源中。例如,如果客户需要我的所有用户users
表中年龄在 20 岁到 30 岁之间,住在加利福尼亚州,距离旧金山 10 英里,并且在过去 6 个月内购买过一本书,这可以用 ReQL(RethinkDB 的查询语言)来表达,并且变更源可以为该查询进行设置,以便客户端仅在以下情况时收到通知relevant变化。仅使用 Socket.io 和 Node.js 很难做到这一点。
3. 可扩展性
RethinkDB 解决的最后一个问题是,它是一种更具可扩展性的解决方案,只需将所有内容存储在内存中(通过 Socket.io 和 Node.js)。由于 RethinkDB 是从头开始构建的分布式数据库,因此您可以拥有一个包含 20 多个带有分片和副本的 RethinkDB 节点的集群。默认情况下,您编写的每个 RethinkDB 查询都是分布式的。现在,您可以拥有 20 多个其他无状态 Node.js 节点,并且都在侦听 changfeed。因为数据库是事实的中心来源,所以这不是问题。
另一种方法是将自己限制在一台服务器上,拥有其他一些发布/订阅系统(例如,基于 Reddis 之类的系统构建),只有一个可供轮询的数据库......可能还有更多示例,但您可以看到在哪里我就这样吧。
我很想知道这是否回答了你的问题以及我是否明白你的意思。一开始了解如何构建应用程序有点困难,但对于大多数实时架构来说,它确实是一个优雅的解决方案。