我正在使用PhantomJS(一种命令行工具)来渲染网站图像,我希望并行运行其中一些而不是一个接一个地执行。我怎么能这样做?
答案 0 :(得分:3)
以下是使用Resque的示例。注意我为了简洁而离开了...你应该从不直接将外部输入传递给shell命令。
class RasterizeWebPageJob
@queue = :screenshots
def self.perform(url)
system("/usr/bin/env DISPLAY=:1 phantomjs rasterize.js #{url} ...")
end
end
10.times { Resque.enqueue(RasterizeWebPageJob, "http://google.com/") }
如果您正在运行足够的工作人员(并且有可用的工作人员),他们将并行执行。这里重要的是你将单独的作业放在队列中,而不是在一个作业中处理多个屏幕截图。
我建议不要在Rails控制器中使用Thread.new
。队列比线程更容易管理(也更安全)。
答案 1 :(得分:1)
有多种方法可以做到这一点。您正在寻找的是在后台执行异步作业。该视频可能有所帮助:http://railscasts.com/episodes/128-starling-and-workling
答案 2 :(得分:0)
我认为这些其他答案可能缺失的是提供您想要使用的设计模式的基础教育。是的,Resque或Starling以及Workling或Resque与Foreman相结合将是很好的解决方案,但您可能想知道原因。
我相信你想要使用的模式是Observer Pattern或Publisher-Subscriber或PubSub。在最简单的情况下,这个想法类似于打印机的工作方式。
某人(发布者)点击打印,例如网络浏览器。然后,异步,打印机打印它们。如果打印机未打开,打印机将在打开时接收消息。如果多人将文档发送到打印机,打印机将按顺序(FIFO)选择它们,然后处理(打印)它们。如果有多个打印机监听同一个队列(这是因为你通常没有那个隐喻,所以他们可以依次选择消息来更快地处理队列。
Resque和其他PubSub宝石,项目,JAR(你不仅限于Ruby)实现了这种设计模式。
有关此模式的更多信息(请注意,Java Observable是一个设计决策不好的类。您可以实现自己的模式):
http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html http://docs.oracle.com/javase/7/docs/api/java/util/Observable.html http://en.wikipedia.org/wiki/Observer_pattern http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
对于我们的处理,我们使用Resque来处理较小的任务,但是你仍然只能使用全局解释器锁和其他问题,例如必须将代码部署到服务器,安装gem等。我们现在使用Storm({{3处理我们的流处理,它的工作方式更好。根据你一天中处理的图像数量,风暴可能对你正在尝试做的事情有些过分。