2014-10-07 39 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根据收到的最后一次确认决定哪一个是空闲的,并相应地发送消息。

希望这会有所帮助。

相关问题