Блокировка в очереди RabbitMQ для предотвращения условий гонки

#rabbitmq

#rabbitmq

Вопрос:

Есть ли простой способ реализовать что-то вроде «блокировки» для предотвращения условий гонки в очереди RabbitMQ при использовании ack?

У меня следующая проблема — у меня есть пара клиентов, использующих очередь с помощью ack. Всякий раз, когда клиент получает сообщение, он подтверждает его и обрабатывает. Однако, если по какой-либо причине обработка завершается с ошибкой, я бы хотел, чтобы сообщение было возвращено в очередь.

Комментарии:

1. Если вы потребляете в режиме подтверждения, то, когда потребителю не удается подтвердить сообщение, сообщение будет помещено обратно в очередь. Это поведение RabbitMQ по умолчанию. Вы испытываете что-то другое?

2. Да, но если вам нужно выполнить какую-то обработку, которая по какой-то причине может завершиться неудачей — скажем, вам нужна секунда или около того, чтобы обработать сообщение. Если вы подтвердите сообщение при первом его получении, в случае сбоя обработки сообщение никогда не будет успешно обработано. Если вы подтвердите сообщение после завершения обработки, вы рискуете, что другой работник перехватит его и обработает до того, как вы подтвердите ответ, и сообщение будет обработано дважды.

3. ДА. Это одна из причин, по которой потребители должны быть идемпотентными, когда это возможно.

4. Если вы не подтвердили его, rabbit не отправит его второму потребителю. Может случиться так, что ack не удается достичь, а затем при повторном подключении к каналу сообщение отправляется снова.

Ответ №1:

Просто обработайте его, а затем подтвердите его. И если обработка завершается неудачно, отправьте сообщение с ack помощью или nack .

 QueueingConsumer consumer = new QueueingConsumer(channel);
boolean autoAck = false;
channel.basicConsume("hello", autoAck, consumer);


QueueingConsumer.Delivery delivery = consumer.nextDelivery();
//do your processing    
boolean requeue = false;
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), requeue);
 

Комментарии:

1. Я боюсь, что это не решит условие гонки, поскольку второй потребитель повторяет ту же логику по тому же сообщению