RabbitMQ basic.get и подтверждение

Я призываю:

GetResponse response = channel.basicGet("some.queue", false); // no auto-ack
....
channel.basicAck(deliveryTag, ...);

Однако, когда я вызываю basicGet, сообщения в очереди остаются в состоянии «Готово», а не в состоянии «Не подтверждено». Я хочу, чтобы они были в неподтвержденном состоянии, чтобы я мог либо basic.ack их (таким образом, исключить их из очереди), либо basic.nack их


person Bozho    schedule 21.10.2011    source источник


Ответы (2)


Я делаю следующее, чтобы имитировать задержку подтверждения:

Во время потребления

  1. Получить (использовать) сообщение из начальной очереди.
  2. Create a "PendingAck_123456" Queue.
    123456 is a unique id of the message.
    Set the following properties
    • x-message-ttl (to requeue after timeout)
    • x-expires (чтобы убедиться, что временная очередь будет удалена)
    • x-dead-letter-exchange и x-deal-letter-routing-key для повторной постановки в исходную очередь по истечении TTL.
  3. Опубликовать сообщение Pending ack в этой очереди "PendingAck_123456"
  4. Подтвердите сообщение, чтобы удалить его из начальной очереди

Во время подтверждения

  1. Рассчитать имя очереди из идентификатора сообщения и получить из очереди «PendingAck_123456»
  2. Подтвердите это (не нужно вызывать .getBody() ).
    Это удалит его из этой очереди ожидания, не позволяя TTL повторно поставить его в очередь.

Примечания

  • Очередь только для 1 сообщения. Является ли это проблемой, если таких очередей много?
  • Сообщение, помещенное в очередь, будет отправлено на стороне входа в очередь, а не на выходе из очереди (как при реальном подтверждении). Это влияет на порядок сообщений.
  • Сообщение копируется приложением в очередь ожидания. Это дополнительный шаг, который может повлиять на общую производительность.
  • Чтобы имитировать Nack/Reject, вы можете скопировать сообщение в начальную очередь и подтвердить его из очереди PendingAck. По умолчанию это сделает TTL (позже).
person Myobis    schedule 13.01.2014

При выполнении ack сразу после get все работает нормально. Однако в моем случае они были разделены запросом. А шаблон spring закрывает канал и соединение при каждом выполнении. Итак, есть три варианта:

  • держать открытыми один канал и соединение в течение всего срока службы приложения
  • иметь какую-то область диалога (или в худшем случае: использовать сеанс), чтобы сохранить один и тот же канал и повторно использовать его.
  • использовать один канал для каждого запроса, немедленно подтверждать получение и сохранять сообщения в памяти.

В первых двух случаях вы не можете сделать это с помощью Spring RabbitTemplate

person Bozho    schedule 24.10.2011