水平扩展

水平扩展任何实时系统都可能很复杂,尤其是在处理长期连接(如 WebSockets)时。考虑以下示例,其中客户端 A 订阅了由客户端 B 触发的某个事件。

diagram1
图 1. 基本订阅设置示例

运行 GraphQL 服务的服务器执行以下操作:

  1. 接收客户端 B 的变异。

  2. 在 Neo4j 上运行 Cypher 查询。

  3. 触发客户端 A 的订阅事件。

此设置适用于 @neo4j/graphql 服务器的单个实例。但是,当尝试通过添加更多 GraphQL 服务器进行水平扩展时,您可能会遇到以下情况:

diagram2
图 2. 具有 2 个服务器的订阅

在这种情况下,客户端 A 订阅了一个服务器。但是,当客户端 B 触发变异时,它可能会查询不同的服务器。

更改在数据库中成功发生,并且连接到同一服务器的任何客户端都会收到订阅事件。但是,客户端 A 不会收到任何更新,因为它连接的服务器不会收到任何变异的通知。

这是库提供的订阅引擎的默认行为,使其不适合在水平扩展的环境中使用。

使用 PubSub

解决此问题的一种方法(以及 @neo4j/graphql 的预期工作方式)是使用带有外部代理的 PubSub 模式来通过多个实例广播事件。这可以通过不同的 订阅引擎 来实现。

按照前面的示例,使用中间代理在所有实例之间广播事件,基础架构将如下所示:

diagram3
图 3. 具有 2 个服务器和消息代理的订阅

事件如下:

  1. 客户端 B 查询第一个服务器。

  2. 服务器在数据库中执行变异。

  3. 同一服务器向代理发送事件。

  4. 然后,代理通知每个服务器(广播),包括最初触发事件的服务器。

  5. 两个服务器都接收通知并触发其订阅客户端的任何事件。

进一步阅读

您可以在 订阅引擎 上找到更多使用 @neo4j/graphql 的此类模式示例。