我正在使用命令行工具 PhantomJS 来渲染网站的图像,我想并行运行其中的一些,而不是一个接一个地运行。我怎样才能做到这一点?
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/") }
如果您运行了足够的工作人员(并且有可用的工作人员),它们将并行执行。这里重要的是您将单独的作业放入队列中,而不是在一个作业中处理多个屏幕截图。
我建议不要Thread.new
在 Rails 控制器中使用。队列比线程更容易(也更安全)管理。
有多种方法可以做到这一点。您正在寻找的是在后台执行异步作业。该视频可能会有所帮助:http ://railscasts.com/episodes/128-starling-and-workling
我认为这些其他答案可能缺少的是提供有关您想要使用的设计模式的基础教育。是的,Resque 或 Starling 以及 Workling 或 Resque 与 Foreman 相结合将是很好的解决方案,但您可能想知道原因。
我相信您想要使用的模式是观察者模式或发布者-订阅者或 PubSub,简称。这个想法类似于打印机的工作方式,在最简单的情况下。
一个人(发布者)在网络浏览器中点击打印。然后,打印机异步打印它们。如果打印机没有打开,它会在打开时接收消息。如果多人向打印机发送文档,打印机将按顺序选择它们(FIFO)然后处理(打印)它们。如果有多个打印机正在监听同一个队列(这是比喻失效的地方,因为您通常没有那个),那么他们可以依次选择消息以更快地处理队列。
Resque 和其他 PubSub gem、项目、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 ( https://github.com)。 com/nathanmarz/storm)来处理我们的流处理,它工作得更好。Storm 可能对你想要做的事情来说太过分了,这取决于你一天要处理多少张图像。