在Rails应用程序中进行长轮询

时间:2015-08-29 12:41:34

标签: ruby-on-rails websocket passenger long-polling faye

我的应用程序有一个页面,用户必须在该页面上相对实时地查看如何处理2个步骤。

现在这是由 ajax短轮询完成的。我想把它改成一些服务器重量较少的技术,我选择 Faye gem ajax long-polling
Ajax长轮询更容易实现,不需要任何服务器入侵。它将需要4个ajax请求(用于完成2个步骤的页面) 王菲宝石将发送3个请求,这不会少很多。它需要我设置我的nginx-passenger服务器,并且通常更难实现和支持。

我会选择 ajax long-polling ,但我听说在请求被长时间轮询时需要运行整个Rails实例,这将耗尽我的RAM。 另一方面,从How rails server on production works?我知道Rails可能没有长轮询的问题。那么,真实的, - 来自多个客户端的 ajax长轮询需要多个并发应用程序处理(这可能会占用我的一些资源,不确定哪些资源)?

1 个答案:

答案 0 :(得分:12)

你的问题提出了三种不同技术的可能性:

  • Websockets(FayePleziEM-Websockets或您喜欢的任何websocket解决方案。
  • 短轮询(基于客户端'拉式'样式通知)。
  • 长轮询(客户端和服务器尝试持久连接 - pre websockets技术)。

虽然Websockets似乎是推送通知最具扩展性和自然性的解决方案,但它 - 就像大多数情况一样 - 是一个特定于应用程序的问题。您需要考虑您的资源和需求,并以最佳方式平衡它们。

Websockets vs. Short-polling每个都带有"价格"。虽然短轮询更容易实现,但Websockets允许真正的"推送"他们的设计旨在保护网络和服务器资源。

对于Websockets与长轮询,答案很简单 - Websockets效率更高。

长轮询通过阻止浏览器发送的HTTP请求来模拟持久连接,直到服务器有数据来回答"用。这可能会阻止整个服务器,如果它的并发性不高效,它显然会阻止负责回答请求的线程(服务器的线程池中有多少个线程?8?24 ?)。

相比之下,Websockets 持久性连接,它们不会阻塞,而是与服务器集成。它是一个更加优雅和资源友好的解决方案。

您可以在此处找到有关长轮询与短轮询的更多信息:

示例

假设您希望在任何特定时刻连接到您网站的5,000个活跃客户端(如果每个客户每天花费30分钟连接,则假定总共约240K客户端,无视峰值和ebbs是使用时间)。

现在,让我们仅针对应用的push / update部分比较资源:

  • 短轮询:如果每个客户端每2秒发送一次更新查询(不是很快,但不是太慢,根据您的需要而定),您只需处理2,500个请求/秒回答更新查询请求。每个请求都会影响应用的内存,性能和响应能力。

  • 长轮询:您将有5000个连接已阻止并等待响应。这5000个任务可能每个都使用一个线程......即使你设法使用一些异步响应和一个线程池(使用Rack服务器超级困难)来循环任务,你也会吃掉CPU和内存等待更新。此外,每次更新都需要您续订5,000个连接(或者,如果您很幸运,HTTP / 1.1&keep-alive功能将为您免除此不便)。这些被阻止的连接将影响应用程序的响应能力和性能,使用CPU周期并从实际请求中获得焦点。它可能(或可能不)比尝试每秒回答2,500个请求更好......但效果不是很好。立即推送数据。

  • Websockets :您将有5,000个连接添加到服务器的IO reactor。只要有任何活动(可能永远不会发生)并且没有任何线程被阻止,就会调用websocket回调。使用websocket连接发送的更新不会导致连接关闭,因此无需每次更新都更新连接。立即推送数据。

结束

按照设计,如果你有自己的服务器,你应该能够使用Websockets服务更多的客户端,而不是使用Short或Long轮询。

然而:

  1. Websockets(以及长轮询)比短轮询更难编码(它们使用非常宝贵的资源,这是人工编码时间);

  2. 一些托管服务(即Heroku)将限制websocket客户端的数量,使得"数学"不太确定......另一方面,这些相同服务的并发限制(req / sec)可能最终会支持websockets。