Parallel processing Spring AMQP RabbitMQ如何使两个并行使用者不会同时抓取相同的任务?

Parallel processing Spring AMQP RabbitMQ如何使两个并行使用者不会同时抓取相同的任务?,parallel-processing,rabbitmq,spring-integration,Parallel Processing,Rabbitmq,Spring Integration,我有两个系统与RabbitMQ集成 背景 客户端将多个请求消息从Spring AMQP出站网关发送到RabbitMQExchange,rabbitmq-DirectExchange将使用循环调度将这些消息分派给多个工作者(这些工作线程独立于不同的桌面上,它们将并行运行相同的工作线程代码,以便使用simpleMessageListner处理来自RabbitExchange的不同消息 逻辑流 类似于 客户端----sendRequests(5个任务)到-->RabbitMQ DirectExch

我有两个系统与RabbitMQ集成


背景

客户端将多个请求消息从Spring AMQP出站网关发送到RabbitMQExchange,rabbitmq-DirectExchange将使用循环调度将这些消息分派给多个工作者(这些工作线程独立于不同的桌面上,它们将并行运行相同的工作线程代码,以便使用simpleMessageListner处理来自RabbitExchange的不同消息


逻辑流

类似于

客户端----sendRequests(5个任务)到-->RabbitMQ DirectExchange

然后Rabbitmq DirectExchange将这5项任务分配给工作人员 PC1(工人1)PC2(工人2)


ExchangeType和我的绑定



用户配置的工人


Worker类是简单的POJO,它将处理请求并完成任务


使用:RabbitMQ 3.2.2Spring集成Amqp 2.2


我的期望

我希望Worker1可以接收部分任务,而Worker2可以选择其余任务(其他任务)

我希望工作人员能够并行执行全部5项任务。每次每个工作人员只执行一项任务,完成后将逐个分配另一项任务。(兔子列表器已设置为预取=1

比如

工作人员1:t2 t3 t5

工人2:t1 t4

但是

经过大量的运行时测试,有时它会正确地完成任务

工人1——任务4任务1

工人2——任务3任务2任务5

但有时它会以这样的方式做错事:

工人1——任务4任务1

工人2——任务4任务2任务1

task4和task1分别由worker1和worker2 sametime选择


运行时测试: 我检查了客户端是否正确向RabbitExchange发送task1 task2 task3 task4 task5请求消息。但每次每个工作人员都接收到不同的任务。有一种常见情况可能会触发错误的调度

RabbitmqExchange中有5个任务(t1、t2、t3、t4、t5),它们将被发送到2个并行工作线程(w1、w2)

w1获得任务:t2 t1 t4

w2获得任务:t3 t1

作为循环调度方法,w1和w2依次得到任务

w1gott2w2gott3

在运行t2t3时,RabbitmqExchange将t1发送到w1,并等待来自w1的确认

假设t2t3花费更多的时间来完成任务,并且w1执行t1w2是空闲的

w2finisht3任务将收到RabbitmqExchange调度t1,因为w2不忙,并且RabbitExchange未收到t1已完成任务确认消息

我的理解是

w1w2都在执行相同的任务t1。它们中的任何一个一旦完成t1就会将ack发送回RabbitmqExchange,然后RabbitmqExchange将退出一条任务消息的队列。由于t1已经完成了两次,RabbitmqExchange将退出另一条任务消息的队列应该是这样的。因此,通过这种方式,t5消息已退出队列,因为t1已执行了两次。虽然RabbitmqExchange中的5条消息已确认并退出队列完成。但有两个工作进程缺少dot5和dot1两次


我应该怎么做才能防止两个并行工作人员从同一个兔子队列中获取相同的消息? I尝试了自动确认方式,消息已正确确认。但在服务器等待工作方确认期间,rabbitmq可能会重新修补未确认但已分发给另一个工作方的消息

同时考虑同步发送的消息或优先发送消息。但没有明确的目标如何实现


我很高兴听到关于这个问题的任何想法。谢谢。我认为造成您的消费者出现重复消息的一个原因是,消费者在发送确认消息之前关闭了频道

在这种情况下,RabbitMQ代理将重新查询消息,并将其重新传递标志设置为。从RabbitMQ:

如果将消息传递给使用者,然后重新查询(例如,因为在使用者连接断开之前未对其进行确认),则RabbitMQ将在再次传递消息时(无论是传递给同一使用者还是其他使用者)在其上设置重新传递标志。这是一个提示,表明使用者以前可能见过此消息(虽然不能保证这一点,但在连接断开之前,消息可能已从代理中发出,但未进入使用者)。相反,如果未设置“重新传递”标志,则可以保证消息以前未被看到。因此,如果使用者发现重复数据消除消息的成本更高