【问题标题】:ajax, long polling and managing two minute retriesajax,长轮询和管理两分钟重试
【发布时间】:2011-12-15 03:07:28
【问题描述】:

对我的 node.js 服务器的 AJAX 请求之一有时可能需要超过两分钟。我发现当服务器花费的时间超过两分钟时,客户端会重新发送 AJAX 请求。这导致服务器更加陷入困境,因为它启动了第二个昂贵的进程。

为了解决这个问题,我在服务器上实现了一个长轮询解决方案。客户端对服务器上的检查函数进行 ajax 调用,该函数仅检查进程是否完成并每五秒重新检查一次,完成后返回客户端。

但是,我仍然有两分钟问题的变体。两分钟后,第二次检查 AJAX 仍然调用。然后两个检查都在运行,似乎只有新的检查会与客户端通信。

解决这个问题的最佳方法是什么?

  • 有没有办法配置或禁用两分钟 ajax 重发?
  • 有没有更好的方法来管理对服务器的后续重复请求?
  • 我需要在客户端而不是服务器上实现超时吗?

我正在使用 jQuery AJAX 调用,Chrome 浏览器上的 node.js 服务器

更新:来自node.js docs,“所有传入连接的默认超时时间为 2 分钟”。我仍然对有关编写长时间运行的服务器请求的最佳实践的建议感兴趣,其中客户端在服务器完成之前不需要知道任何内容。

【问题讨论】:

    标签: ajax jquery node.js long-polling


    【解决方案1】:

    要清楚正在发生的事情:

    1. 客户端发送请求“为我做这件事......”
    2. 节点代码启动异步操作(或多个链接在一起)
    3. 两分钟过去了
    4. HTTP 请求超时
    5. 客户端重新发送请求
    6. 现在有两个请求正在运行
    7. 以此类推,直到有大量请求在运行

    我想我听说过这叫做“狗桩效应”。我不知道 node.js 或 jQuery 中有任何标准库可以帮助你,尽管有人已经开始使用缓存代理来帮助解决这个问题,以防响应是“可缓存的”:

    https://github.com/simonw/dogproxy

    因此,您必须设计自己的系统来解决这个问题。

    处理批处理作业有不同的方法,而且通常取决于作业的性质。

    对于需要很长时间的任务,我最常见的是 API 会立即返回作业的 ID,然后客户端使用轮询(或长轮询)来等待作业完成。您将需要某种数据库来存储作业的状态(完成百分比)和结果,并允许客户端等待该状态更改。这也可以让您“取消”作业,但在这种情况下,服务器端代码必须定期检查它是否已被取消。

    请注意,如果应用程序正在或将在以后扩展,则无论您在何处存储作业状态,都必须由集群中的所有节点共享。您可能会为此使用某种高速轻量级存储系统,例如 memcached 或 redis。

    【讨论】:

    • 感谢您清楚地解释我一直在跌跌撞撞的方向。节点的异步理念似乎不一致,必须进行轮询。
    • 您希望在 Chrome Inspector 中看到第二个请求(重试)吗?我的行为与上述 2 分钟后重试的行为相同,但没有迹象表明是客户端重试还是服务器正在重试。
    • Emile,我不认为服务器通常能够触发客户端重试 - 一旦连接被转储,客户端必须重新连接自己。因此,如果您正在记录网络事件,它应该显示在 Chrome Inspector 中。但是,如果重试是由某个中间代理执行的,那么您将不会在客户端上看到它,并且您将无法控制它。由于 HTTP 和 Internet 的无状态不可靠 mdeium 和一般互联网,让客户端等待超过几秒钟以完成服务器操作通常效果不佳。
    • Paul:这与异步哲学不一致。在理想的异步世界中,您应该给服务器一个 URL 来发送回复,而不是等待或轮询回复。不幸的是,在“可达性”方面,互联网上的客户端和服务器之间存在很大的不对称性,因此服务器很难回调客户端(假设 javascript 甚至提供了这样做的机制)。长轮询工作正常,不会产生太多额外开销。对于大多数应用程序来说,这些长时间运行的操作应该很少见。
    猜你喜欢
    • 2012-02-24
    • 2012-07-07
    • 2011-04-20
    • 1970-01-01
    • 2012-08-16
    • 2012-05-17
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多