如何使用Rails和Heroku创建多个并行并发请求

时间:2017-05-19 23:33:10

标签: ruby-on-rails ruby heroku concurrency resque

我目前正在开发一个Rails应用程序,它将一长串链接作为输入,使用后台工作程序(Resque)擦除它们,然后将结果提供给用户。但是,在某些情况下,有很多URL,我希望能够并行/并发多个请求,这样可以花费更少的时间,而不是等待一个请求完成一个页面,抓取它,并且继续下一个。

有没有办法在heroku / rails中执行此操作?我在哪里可以找到更多信息?

我遇到了resque-pool,但我不确定它是否会解决这个问题和/或如何实现。我还读到了使用不同类型的服务器来运行rails以使并发成为可能,但我不知道如何修改当前的情况以利用这一点。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

请勿使用Resque。请改用Sidekiq

Resque在单线程进程中运行,这意味着工作程序同步运行,而Sidekiq在多线程进程中运行,这意味着工作程序在不同的线程中异步/同步运行。

确保为每个工作人员分配一个URL。如果一个工作人员刮掉多个URL是没用的。

使用Sidekiq,您可以将链接传递给工作人员,例如

LINKS = [...]
LINKS.each do |link|
  ScrapeWoker.perform_async(link)
end

perform_async实际上并不会立即执行作业。相反,链接只是与工作类一起放在redis队列中,依此类推,稍后(可能在几毫秒之后),工作人员被分配为通过运行{{1}来在自己的线程中执行队列中的每个作业。 ScrapeWorker中的实例方法。如果在执行worker期间发生异常,perform将确保再次重试。

PS:您没有传递给工作人员的链接。您可以将链接存储到表中,然后将Sidekiq个记录传递给工作人员。

More info about sidekiq

答案 1 :(得分:0)

将这两行添加到您的代码中还可以让您等到上一个作业完成后再继续:

  • 此行确保您的程序在检查所有作业完成之前等待至少一个作业入队,以避免将未填充的队列误解为所有作业的完成

sleep(0.2) until Sidekiq::Queue.new.size > 0 || Sidekiq::Workers.new.size > 0

  • 此行确保您的程序等待所有工作完成

sleep(0.5) until Sidekiq::Workers.new.size == 0 && Sidekiq::Queue.new.size == 0