2014-10-07 138 views
1

我有一個web應用程序,用戶上傳由web應用程序處理的文件。我做的第一件事就是將請求放入RabbitMQ隊列中。然後,這些請求將在後臺逐個排隊處理。所有這些工作正常。在一個web應用程序中使用RabbitMQ,多個線程可以在同一個隊列上工作

從我的分析,我已經注意到,當隊列中的一個請求花費很長時間來處理時,問題就出現了。發生這種情況時,長時間運行的請求背後的請求也會延遲。

User 1 uploads DOC file at 12:32:10* 
User 2 uploads DOCX file at 12:32:11* 
User 3 uploads PDF file at 12:32:12* 
User 1 uploads PPT file at 12:32:13* 

* -日期時間戳反映,然後請求創建

此時隊列是這樣和DB順序如下:

DOC, DOCX, PDF, PPT 

我知道PDF文件需要更長的時間來處理,但PPT不需要很長時間。由於PDFPPT之前處理,所以PPT也需要很長時間才能完成。

所有請求進行處理後,在DB的時間戳是這樣的:

User 1 uploads DOC file at 12:32:10*  12:32:11** 
User 2 uploads DOCX file at 12:32:11*  12:32:12** 
User 3 uploads PDF file at 12:32:12*  12:32:20** 
User 1 uploads PPT file at 12:32:13*  12:32:40** 

** -以反映隨後的請求結束

通知DB中的日期時間戳PPT需要27僅僅因爲它在PDF之後才完成。在我的測試,如果是以前PDF那麼只需要2 to 3

PS:我使用的是RabbitMQ的插件在Grails應用

問題

有沒有辦法有多個線程在Web應用程序中處理隊列中的請求?我在想,如果多個線程在隊列中工作,那麼即使一個請求(上面的例子中的PDF)花費較長時間來處理其他請求仍然可以完成(上面示例中的PPT)?如果是這樣,我如何強制多個線程在隊列上工作?

有沒有更好的架構,我應該利用這樣的請求得到更快處理,而不是等待處理需要很長時間的請求?

+0

目前尚不清楚你想要什麼。你想在單個Web請求期間使用多個線程開始同時使用來自同一個隊列的消息嗎?如果是這樣,那麼就做吧。沒關係,但要注意客戶端庫的實現,以便在多線程環境中正確使用它。如果您擔心某些消費者正在處理長時間的郵件,那就沒問題。停滯的消息不會阻止其他消費者消費的消息。 – pinepain 2014-10-07 14:01:50

+0

@ zaq178miami是的,我想要多個線程在隊列上工作,以便長時間運行的任務不會延遲處理它後面的任務。我用一個詳細的例子更新了我的問題 – birdy 2014-10-07 14:49:48

回答

0

也許你想要的是讓多個消費者連接到你的隊列中。所以,當一個消費者處理PDF時,另一個消費者可以處理下一個文件。

對於您的情況,您可能還希望basic_qos的值較低。看看這個教程:http://www.rabbitmq.com/tutorials/tutorial-two-java.html

這種模式所知道的competing consumers這裏:http://www.eaipatterns.com/CompetingConsumers.html

+0

嗯,我被「多個消費者」所迷惑。處理PDF(和PPT)的代碼是我的Web應用程序的一部分。這是否意味着我需要將這些代碼移出並將它們轉換爲不同的應用程序/服務? – birdy 2014-10-07 18:00:05

+0

FWIW,我正在使用這個插件與RabbitMQ一起工作http://grails.org/plugin/rabbitmq – birdy 2014-10-07 18:01:57

+0

我不習慣grails,但在RabbitMQ中,您通常會將您的使用者與您的webapp分開運行在背景中。然後你可以運行它們的許多實例 – 2014-10-07 21:12:35

0

那不是打使用隊列的目的是什麼?我們有一個使用RabbitMQ的類似應用程序。我們所做的是爲每種類型設置不同的隊列。所以如果它的pdf,我們有一個pdf隊列,一個ppt隊列,一個doc隊列和一個docx隊列。

我們使用Java和Octobot作爲連接到MQ的客戶端。所以我們可以使用同一個jar文件,並列出所有隊列的yml文件。 JSON具有任務名稱。它在發送到隊列中的每個json消息中都是相同的。所以同一個班級在所有情況下都適用。

也regd競爭消費者...我認爲我們也這樣做..我們有多個運行octobot(Java)的服務器實例。所以這些在RabbitMQ服務器上註冊爲消費者。 因此,RabbitMQ根據收到的最後一次確認決定哪一個是空閒的,並相應地發送消息。

希望這會有所幫助。

相關問題