Ajax、长轮询和管理两分钟重试

3
我的node.js服务器中的其中一个AJAX请求有时会超过两分钟。我发现当服务器花费的时间超过两分钟时,客户端会重新发送AJAX请求。这导致服务器陷入更加困难的境地,因为它开始了第二个昂贵的进程。
为了解决这个问题,我在服务器上实现了长轮询解决方案。客户端对服务器上的检查函数进行ajax调用,该函数仅检查进程是否已完成,并每五秒重新检查一次,直到完成并返回给客户端。
然而,我仍然遇到了两分钟问题的变化。两分钟后又来了第二个检查AJAX调用。然后两个检查都在运行,似乎只有新的请求才会与客户端通信。
有什么最好的方法来解决这个问题呢?
  • 是否有方法可以配置或禁用两分钟的ajax重新发送?
  • 是否有更好的方式来管理对服务器的后续重复请求?
  • 我需要在客户端上实现超时,而不是在服务器上吗?
我正在使用jQuery AJAX调用,在Chrome浏览器上的node.js服务器。
更新:根据node.js文档,“所有传入连接的默认超时时间为2分钟”。我仍然对编写长时间运行的服务器请求的最佳实践建议感兴趣,其中客户端在服务器完成之前不需要知道任何信息。
1个回答

5
为了清楚地说明正在发生的事情:
1.客户端发送请求“为我做这件事…” 2.Node代码启动异步操作(或多个链接在一起) 3.两分钟过去了 4.HTTP请求超时 5.客户端重新发送请求 6.现在有两个请求正在运行 7.以此类推,直到有大量请求正在运行
我认为这被称为“堆积效应”。我不知道在node.js或jQuery中是否有任何标准库可以帮助您,尽管有人已经开始编写缓存代理来帮助处理响应将是“可缓存”的情况:

https://github.com/simonw/dogproxy

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

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

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

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


感谢您清晰地解释了我一直在摸索的问题。在Node的异步哲学中,不得不进行轮询似乎是一种不一致性。 - Paul Beusterien
你会在Chrome Inspector中看到第二个请求(重试)吗?我遇到了与上述描述相同的行为,即每隔2分钟重试一次,但无法确定是客户端还是服务器在重试。 - emilebaizel
Emile,我认为服务器通常无法触发客户端的重试 - 一旦连接被断开,客户端必须重新连接。因此,如果您正在记录网络事件,则应该在Chrome Inspector中显示。但是,如果重试是由某个中间代理执行的,则您在客户端上看不到它,并且无法控制它。由于HTTP和互联网的无状态不可靠性质,让客户端等待超过几秒钟以完成服务器操作通常不会有好结果。 - Dobes Vandermeer
Paul:这是异步哲学的不一致之处。在理想的异步世界中,您会给服务器一个URL来发送回复,而不是等待或轮询响应。不幸的是,在互联网上,当涉及到“可达性”时,客户端和服务器之间存在重大的不对称性,因此服务器很难回调客户端(假设JavaScript甚至提供了这样的机制)。长轮询效果还不错,并且不会产生太多额外的开销。对于大多数应用程序来说,这些长时间运行的操作应该相当罕见。 - Dobes Vandermeer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接