对我的 node.js 服务器的 AJAX 请求之一有时可能需要两分钟以上。我发现当服务器花费的时间超过两分钟时,客户端会重新发送 AJAX 请求。这导致服务器在启动第二个昂贵的进程后变得更加陷入困境。
为了解决这个问题,我在服务器上实现了一个长轮询解决方案。客户端对服务器上的检查函数进行 ajax 调用,该函数仅检查进程是否已完成并每五秒重新检查一次,并在完成后返回给客户端。
但是,我仍然有一个两分钟问题的变体。两分钟后,第二次检查 AJAX 仍然调用。然后两个检查都在运行,似乎只有新的检查会与客户端通信。
解决这个问题的最佳方法是什么?
- 有没有办法配置或禁用两分钟的 ajax 重新发送?
- 是否有更好的方法来管理对服务器的后续重复请求?
- 我是否需要在客户端而非服务器上实现超时?
我正在使用 jQuery AJAX 调用,Chrome 浏览器上的一个 node.js 服务器
更新:来自 node.js docs ,“所有传入连接的默认超时为 2 分钟”。我仍然对有关编写长时间运行的服务器请求的最佳实践的建议感兴趣,在这些请求中,客户端在服务器完成之前不需要知道任何事情。
最佳答案
要弄清楚发生了什么:
- 客户发送请求“为我做这件事......”
- Node 代码启动一个异步操作(或几个链接在一起)
- 两分钟过去了
- HTTP 请求超时
- 客户端重新发送请求
- 现在有两个请求在运行
- 依此类推,直到有大量请求在运行
我想我听说过这种叫做“狗堆效应”的现象。我不知道 node.js 或 jQuery 中有任何标准库可以帮助您,尽管有人已经开始研究缓存代理以在响应“可缓存”的情况下提供帮助:
https://github.com/simonw/dogproxy
因此,您必须设计自己的系统来解决这个问题。
处理批处理作业有多种方法,通常取决于作业的性质。
对于需要很长时间的任务,我最常见的情况是 API 立即返回作业的 ID,然后客户端使用轮询(或长轮询)等待作业完成。您需要某种数据库来存储作业的状态(完成百分比)和结果,并允许客户端等待该状态发生变化。这也可以让您“取消”作业,尽管在这种情况下,服务器端代码必须定期检查它是否已被取消。
请注意,无论您将作业状态存储在何处,如果应用程序正在或将在以后扩展,则集群中的所有 Node 都必须共享作业状态。为此,您可能会使用某种高速轻量级存储系统,例如 memcached 或 redis。
关于ajax,长轮询和管理两分钟重试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7892949/