RabbitMQ basic.получение и подтверждение

#java #rabbitmq #amqp #spring-rabbit #spring-amqp

#java #rabbitmq #amqp #весна-кролик #spring-amqp

Вопрос:

Я вызываю:

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

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

Ответ №1:

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

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

  1. Получить (использовать) сообщение из начальной очереди.
  2. Создайте очередь «PendingAck_123456».
    123456 — это уникальный идентификатор сообщения.
    Задайте следующие свойства

    • x-сообщение-ttl (для запроса после тайм-аута)
    • x-истекает (чтобы убедиться, что временная очередь будет удалена)
    • x-dead-letter-exchange и x-deal-letter-routing-ключ для запроса в начальную очередь по истечении срока действия TTL.
  3. Опубликуйте ожидающее подтверждения сообщение в этой очереди «PendingAck_123456»
  4. Подтвердите сообщение, чтобы удалить его из начальной очереди

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

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

Примечания

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

Ответ №2:

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

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

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