我正在尝试构建一个包含即时消息传递模块的应用程序,其中一个主要挑战是无论用户数量或交换的消息是什么,都可以保持应用程序的可扩展性。
在an article中我读到可以使用带有“订阅”的GraphQL构建实时应用程序,除此之外,它是一个简单易用的protocole,并且具有最小化往返对象检索的优势,因而使用资源较少。
但是,如果我们需要向系统添加新的服务器/节点以便水平扩展呢?这可能是使用GraphQL吗?
以允许水平扩展的websockets实现为例,有SocketCluster。我想知道GraphQL开发的应用程序是否可以跨多个节点/机器进行扩展,或者它必须与SocketCluster等其他框架一起使用才能实现这一目标。
答案 0 :(得分:3)
很快 - 是的。我们已经做到了,它运作良好。
诀窍是,在涉及水平扩展时,您必须更深入地思考API工作者应用程序。如果您想要推送架构,则从一开始就需要异步。
为实现这一目标,我们使用排队系统,即 RabbitMQ 。
想象一下这种报告生成方案,最多可能需要10分钟:
ReportGenerationDoneEvent
的信息,并检查是否有人正在侦听其令牌。ReportGenerationDoneEvent
。它有点广泛,但是通过简单的抽象,您不必考虑所有这些复杂性,并使用此路由为多个服务编写约30行代码。
关于它的精彩之处,你最终得到了良好的横向扩展,事件可重放性(重试),关注点分离(客户端,api,工作者),尽快将数据推送到客户端,以及当你提到你不要在are we done yet?
请求上浪费带宽。
另一个很酷的事情是,只要用户在我们的面板中打开报告列表,他就会看到当前正在生成报告,并且可以订阅他们的更改,因此他们不必手动刷新列表。
很好地思考SocketCluster。它将优化上述方案中的步骤10,但就目前而言,我们看不到将ReportGenerationDoneEvent
广播到整个API群集的任何性能问题。对于更多实例或多区域架构,它将是必须的,因为它将允许更好的缩放和分片。
重要的是要了解SocketCluster在通信层(WebSockets)上运行,但逻辑API层(GraphQL)高于该层。要进行GraphQL订阅,您只需使用允许您将信息推送给用户的通信协议,而WebSockets允许这样做。
我认为使用SocketCluster是一个很好的设计选择,但请记住迭代实现。当您计划在任何单个时间点打开许多套接字时,仅使用SocketCluster。此外,您应该仅在必要时订阅,因为WebSocket是有状态的并且需要管理和心跳。
如果您对我上面使用的异步后端架构更感兴趣,请阅读CQRS和事件源模式。