GraphQL:订阅与定期查询无需刷新即可更新



想象一下,我们想为成千上万的用户提供一个web应用程序。即使用户没有主动刷新页面,页面上的信息也应该保持最新。目前,我们有两种方法来实现这一点:

  • 设置对可能通过GraphQL更改的数据的订阅
  • 在加载的页面上将定期查询设置为GraphQL

以下是一些想法:

  • 数据的更改应在最长30秒后对客户端可见。因此,周期性查询至少需要每30秒运行一次
  • 假设1000名用户同时打开我们的页面,即使他们没有主动查看。如果我们每30秒查询一次,即使没有人主动请求新视图或刷新,也会产生33.3次查询/秒的基本负载
  • 在";最坏的";视图中,可能有60个数据点将通过订阅单独更新。因此,1000个开放标签将是6万个开放订阅

我们想知道推荐哪种解决方案扩展性更好。

  • 是最好运行数千个订阅(本质上是数千个打开的TCP套接字为websocket连接供电),还是最好一次又一次地查询几乎没有变化的数据
  • ";稳态"/"心跳;订阅的打开websocket连接的负载
  • 从服务器的角度来看,打开的websocket或定期查询是否需要GraphQL服务器更多的CPU负载

如果你有这样的权衡经验,如果你能分享它就太好了。

在我看来,30秒的刷新时间远远不够让您认为websocket是必要的。请记住,websocket将不断地ping您的服务器,以保持其在线。如果你的SLA是30秒,那么你会用websocket ping更多。

websocket的主要功能是可以基本上实时地发布给用户。听起来您的应用程序实际上并不需要实时交互。例如,一个聊天应用程序将需要用户看到不断的更新。用户希望他们的新消息在发送后立即出现,此外,您可能需要发送活动指示器,如打字指示器、在线/离线状态和其他实时指示器。听起来您的SLA远未达到该水平。

尽管如此,一个websocket可以扩展到无穷大。一个EC2 r5大型实例可能可以毫无问题地处理数千(甚至数万)个websocket连接(当然,这取决于您将在乒乓球上进行多少处理)。

我将使用;流行的";web应用程序内的更新。当您知道客户需要进行某些更改时,您只能生成一次响应并将其添加到缓存中。对客户的回复将从缓存中获得最新的响应。

诀窍是找出一个与应用程序客户端共享的密钥系统。相反,客户要求任何";视图";在任何时候,它们都会在预设时刻映射到预设视图,您可以确保这些视图是在缓存中预先生成的。

GraphQL订阅

实时更新:GraphQL订阅旨在为客户端提供实时更新。这对于需要在用户界面上反映即时数据更改的应用程序尤其有益。一个用户所做的更改可以立即被查看相同数据的其他用户看到。

减少网络流量:订阅仅在发生实际更改时发送数据,与定期查询相比,这可能会导致通过网络传输的数据减少。这对于带宽有限的移动设备或用户来说尤其重要。

复杂性:实现订阅可能比定期查询更复杂,因为它涉及在客户端和服务器上设置和管理WebSocket连接。订阅的服务器端处理需要额外的基础设施,例如WebSocket服务器。

用户体验:订阅提供了更加无缝和交互式的用户体验,因为更新会实时推送到客户端。需要用户之间协作或通信的应用程序可以从这种即时反馈中获益。

定期查询

可预测负载:定期查询会在服务器上生成稳定的负载,因为请求是以定期间隔发送的。这种可预测性可以使资源分配和扩展更加简单。

带宽消耗:与订阅相比,定期查询可能会消耗更多的带宽,尤其是在频繁更新的情况下。但是,可以通过使用高效的缓存机制来减轻这种影响。

服务器效率:可以批量处理定期查询,这可能允许服务器优化和批处理请求。但是,如果太多客户端同时同步查询,可能会导致性能瓶颈。

延迟:定期查询会在客户端上的数据更改和更新之间引入延迟。客户端可能直到下一个查询才反映最新数据。

混合方法

关键数据与非关键数据:考虑对需要实时更新的关键数据使用订阅,并定期查询时间敏感度较低的数据。这平衡了实时更新的好处和定期查询的效率。

可扩展性:根据应用程序的扩展要求,您可能会对一部分用户(例如高级用户或活跃参与者)使用订阅,并依赖于对其他用户的定期查询。

监控和优化

资源管理:无论采用何种方法,监控资源利用率(包括内存、CPU和网络使用率)都至关重要。正确管理资源可确保最佳性能和可扩展性。

延迟分析:在对延迟敏感的应用程序中,将更新通过订阅到达客户端所需的时间与定期查询引入的延迟进行比较。

负载测试:在各种场景中运行负载测试,查看每种方法在不同级别的用户活动中的表现。

缓存:使用智能缓存策略,通过最大限度地减少冗余查询或重复订阅更新来减少服务器负载和带宽消耗。

最新更新