RabbitMQ:一次多个队列/一个(长)任务

时间:2017-05-22 14:50:47

标签: python rabbitmq

我正在使用RabbitMQ来管理执行持久任务的多个服务器。每个服务器都可以侦听一个或多个队列,但每个服务器一次只能处理一个任务。

每次在服务器中启动使用者时,我都会使用channel.basic_qos(prefetch_count=1)对其进行配置,以便只为相应的队列处理一个任务。

假设我们有:   - 2个队列:task1,task2。   - 2台服务器:server1,server2。   - 两个服务器与task1和task2一起工作

如果同时生成下一条消息:   - tasksA for tasks1   - taskB的messageB   - messagesC for tasks1

我的期望:   - messageA由server1处理   - messageB由server2处理  。 messageC保持排队,直到其中一个服务器准备就绪(完成当前任务)。

我真正得到的是:   - messageA由worker1处理   - messageB由worker2处理   - messageC由worker2处理(错误)

我不会同时启动消费者。实际上,每个服务器中的工作任务都会不断打开/关闭。大多数时间服务器使用不同的队列(server1:tasks1,tasks2,task3; server2:tasks1,tasks5; server3:tasks2,tasks5;等等)。

我怎么能设法做到这一点?

修改 基于Olivier的回答: 任务是不同的。每个服务器都能够处理一些任务,而不是所有任务。服务器一次只能处理一个任务。

我尝试使用与routing_keys的交换,但我发现了两个问题:绑定到路由键task_i的所有服务器都将处理其任务(我需要它只处理一次),如果没有服务器绑定到task_i ,然后删除它的消息(我需要保持排队,直到某个服务器可以处理它)。

1 个答案:

答案 0 :(得分:0)

从您提供的说明中看,问题是由于您的服务器同时连接到多个队列。

当您的预取计数设置为1时,连接到3个队列的服务器将消耗最多3条消息,即使他一次只处理一个(根据您的处理描述)。

从您的问题中不清楚是否需要多个队列,或者您是否可以让所有任务最终都在一个队列中:

  • 让所有服务器都使用所有任务
  • 您是否需要能够停止处理某些任务

如果您需要/希望能够"停止"处理某些任务,或控制整个服务器的处理分配,您需要管理服务器中的消费者,一次只有一个活跃的消费者(否则您将阻止/消费一些预取的消息1)。

如果您不需要控制各种任务的处理,那么将所有消息最终放在一个队列中会更加简单,并且单个使用者可以使用每个服务器的预取一个队列设置。