2011-06-18 156 views
2

我在1.2中发现了a question that explains how Play Framework's await() mechanism works。本质上,如果您需要做一些将会阻塞一段时间的事情(例如,缓慢的外部http请求),您可以暂停您的请求,并释放该工作人员在阻塞时处理其他请求。我猜测,一旦你的阻止操作完成,你的请求被重新安排进行继续处理。这不同于在后台处理器上安排工作,然后让浏览器轮询完成,我想阻止浏览器而不是工作进程。推迟拦截Rails请求

不管我对游戏的假设是否是真信,有没有在Rails应用程序这样的技术?我想可以考虑这是一种长时间轮询,但除了“使用节点”之外,我没有找到关于该主题的许多建议。

回答

3

我对长期的请求,阻止工人采取其他请求了类似的问题。这是所有Web应用程序的问题。即使Node.js可能无法解决在工作人员上花费太多时间的问题,或者可能会耗尽内存。

Web应用程序我对工作有发送请求到Rails的REST API网络接口,那么Rails的控制器有权要求运行繁重耗时的任务,得到一些数据备份节点REST API。从Rails到Node.js的请求可能需要2-3分钟。

我们仍在试图找到不同的方法,但也许以下可以为你工作,或者你能适应的一些想法,我很想得到一些反馈太:

  1. 前端做出的请求Rails API在同一会话中生成标识符[A]。 (该标识符有助于识别来自同一用户会话的先前请求)。
  2. 滑轨API代理前端请求和标识符[A]到Node.js的服务
  3. Node.js的服务此作业添加到队列系统(例如RabbitMQ的,或Redis的),该消息包含识别符[一个]。 (这里你应该根据自己的情况考虑,同时假设系统将消耗队列作业并保存结果)

  4. 如果同一个请求再次发送,根据需要,可以杀死当前作业使用相同的标识符[A]并安排/排列最新请求,或忽略等待第一个请求完成的最新请求,或者其他决策符合您的业务需求。

  5. 前端可以发送间隔REST请求,以检查是否有识别符[A]的数据处理已完成或没有,那么这些要求是重量轻,速度快。

  6. 一旦Node.js的完成作业,您可以使用邮件订阅系统或等待下一次的到来检查状态请求,并将结果返回到前端。

您还可以使用负载平衡器,例如,亚马逊负载平衡器,Haproxy。 37signals有一个blog post and video关于使用Haproxy卸载一些长时间运行的请求,不会阻止较短的请求。

Github上使用类似的策略来处理长期请求生成提交/贡献可视化。他们还设定了拉动时间的限制。如果时间太长,Github会显示一条消息,说它太长了,它已被取消。

YouTube对于排队较长的任务有一个很好的信息:“这需要比预期更长的时间,您的视频已排队并将尽快处理。”

我认为这只是一个解决方案。您还可以看看EventMachine gem,它有助于提高性能,处理程序并行或异步请求。

由于这类问题可能涉及一个或多个服务。考虑提高这些服务(例如数据库,网络,消息协议等)之间性能的可能性,如果缓存可能有帮助,尝试缓存频繁的请求或预先计算结果。