簡體   English   中英

在 Ruby 中並行運行命令行進程

[英]Running command-line processes in parallel in Ruby

我正在使用 PhantomJS(一種命令行工具)來渲染網站的圖像,並且我想並行運行多個這些圖像,而不是一個接一個地執行。 我怎樣才能做到這一點?

這是一個使用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/") }

如果您運行了足夠多的 worker(並且有可用的 worker),它們將並行執行。 這里重要的是將單獨的作業放入隊列,而不是從一個作業中處理多個屏幕截圖。

我建議不要在 Rails 控制器中使用Thread.new 隊列比線程更容易(也更安全)管理。

有多種方法可以做到。 您正在尋找的是在后台執行異步作業。 該視頻可能會有所幫助: 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 用於較小的任務,但您仍然僅限於全局解釋器鎖定和其他問題,例如必須將代碼部署到服務器、安裝 gems 等。我們現在使用 Storm( https://github.com)。 com/nathanmarz/storm ) 來處理我們的流處理,並且效果更好。 Storm 可能對您嘗試做的事情有些過分,這取決於您一天處理的圖像數量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM