我在1.2中找到了a question that explains how Play Framework's await() mechanism works。基本上,如果您需要做一些会阻塞可测量时间的事情(例如,制作一个缓慢的外部http请求),您可以暂停您的请求并释放该工作人员在阻止时处理不同的请求。我猜你的阻止操作完成后,你的请求会被重新安排,以便继续处理。这与在后台处理器上安排工作然后让浏览器轮询完成不同,我想阻止浏览器而不是工作进程。
无论我对Play的假设是否真实,是否有一种技术可以在Rails应用程序中执行此操作?我想人们可以认为这是一种长期民意调查,但除了“使用节点”之外,我没有找到很多关于该主题的建议。
答案 0 :(得分:3)
我有一个类似的问题,关于阻止工人接受其他请求的长请求。这是所有Web应用程序的问题。甚至Node.js也许无法解决在工作者身上花费太多时间的问题,或者只是内存不足。
我工作的Web应用程序有一个Web接口,可以向Rails REST API发送请求,然后Rails控制器必须请求运行耗时的任务的Node REST API来获取一些数据。从Rails到Node.js的请求可能需要2-3分钟。
我们仍在努力寻找不同的方法,但也许以下内容可能适合您,或者您可以调整一些想法,我也希望得到一些反馈:
Node.js服务将此作业添加到队列系统(例如RabbitMQ或Redis),该消息包含标识符[A]。 (这里你应该考虑基于你自己的场景,也假设系统将使用队列作业并保存结果)
如果同一请求再次发送,根据需要,您可以使用相同的标识符[A]终止当前作业并调度/排队最新请求,或忽略等待第一个请求的最新请求完成或其他决定符合您的业务要求。
前端可以发送间隔REST请求来检查标识符[A]的数据处理是否已经完成,然后这些请求是轻量级和快速的。
一旦Node.js完成作业,您可以使用消息订阅系统或等待下一个检查状态请求并将结果返回到前端。
您还可以使用负载均衡器,例如亚马逊负载均衡器Haproxy。 37signals有一个blog post and video关于使用Haproxy卸载一些长时间运行的请求,这些请求不会阻止较短的请求。
Github使用类似的策略来处理生成提交/贡献可视化的长请求。他们还设定了拉动时间的限制。如果时间太长,Github会显示一条消息,说它太长而且已被取消。
对于排长时间较长的任务,YouTube有一条很好的消息:“这比预期花费的时间更长。您的视频已排队,并会尽快处理。”
我认为这只是一个解决方案。您还可以查看EventMachine gem,这有助于提高性能,处理程序并行或异步请求。
由于此类问题可能涉及一项或多项服务。考虑提高这些服务之间的性能的可能性(例如数据库,网络,消息协议等),如果缓存可能有帮助,尝试缓存频繁请求或预先计算结果。