Как подтвердить сообщение с другого канала RabbitTemplate?

Предположим, у меня есть единственный экземпляр rabbitTemplate, и я вызываю rabbitTemplate.send (Message), чтобы опубликовать сообщение на сервер RabbitMQ.

Вот что я хочу сделать: 1. с точки зрения издателя, как убедиться, что сообщение получено RabbitMQ? 2. На стороне потребителя я использую тот же rabbitTemplate для получения сообщения в потоке, и я хочу вручную подтвердить сообщение в другом потоке.

Есть ли способ вручную подтвердить сообщение RabbitTemplate?

Спасибо за любую помощь.


person Tuscany    schedule 03.07.2014    source источник


Ответы (1)


  1. RabbitMQ является асинхронным, поэтому нет возможности «ждать», пока сообщение будет защищено посредником; вы можете включить подтверждения издателя, чтобы получать подтверждение того, что сообщение было доставлено в очередь. Дополнительную информацию см. В документации.

  2. Вы не можете вручную подтвердить сообщение при использовании одного из receive*() методов; вам придется перейти к собственному API с помощью метода execute(); в обратном вызове выполните channel.basicGet(queue, false), чтобы получить сообщение, а затем channel.basicAck(deliveryTag).

person Gary Russell    schedule 03.07.2014
comment
Спасибо и другие вопросы о Channel и deliveryTag. Я получаю сообщение от Channel, вызывая rabbitTemplate.receive *, и сохраняю DeliveryTag этого сообщения. Этот шаг rabbitTemplate закрывает канал, и ACK не возникает в режиме подтверждения вручную. В другом потоке я обрабатываю сообщение и возвращаю результат обработки. наконец, я создаю новый канал с помощью того же rabbitTemplate, чтобы подтвердить или заблокировать сохраненный тег доставки. Но я считаю, что подтверждение не действует. Что происходит? - person Tuscany; 04.07.2014
comment
После поиска в документации и кода отладки я обнаружил, что deviveryTag зависит от канала. Поэтому, когда я подтверждаю сообщение, используя другой канал, ACK не действует, даже если исключение не перехватывается. Лучше я еще раз заявлю, что хочу делать. 1. сообщение опроса клиентов от rabbitmq. 2. исполнитель задачи запускает новый поток для обработки сообщения. Сообщение 3.ACK или NACK зависит от результата обработки сообщения. Как я могу это сделать? Спасибо еще раз. - person Tuscany; 04.07.2014
comment
Вы не можете этого сделать. Вы должны подтверждать сообщения на том же канале. Почему бы вам не использовать Контейнер слушателя? Тогда фреймворк позаботится о ваших аках. - person Gary Russell; 04.07.2014
comment
Спасибо за совет. ChannelAwareMessageListener действительно может вручную ACK-сообщение. Мне нужен потребитель в стиле опроса клиентов, который может дать мне больше возможностей. Например, когда пул потоков задач заполнен, я не беру сообщение из RabbitMQ и просто жду следующего цикла. MessageListener является потребителем в стиле push-сервера, и я не могу перестать получать сообщение, даже если знаю, что пул потоков задач перегружен. - person Tuscany; 05.07.2014
comment
еще один вопрос по каналу. Если канал был случайно закрыт , Есть ли способ создать такой же канал для сообщения ACK? - person Tuscany; 05.07.2014
comment
Верно, но с помощью слушателя вы контролируете параллелизм с контейнером (concurrent-consumers), который вам не нужен / использовать второй пул потоков; вам не нужно ручное подтверждение, позвольте потоку контейнера выполнить подтверждение, когда вы закончите. Нет, вы не можете повторно открыть канал - если он закрыт, сообщение будет снова помещено в очередь в это время. - person Gary Russell; 05.07.2014
comment
Спасибо за совет. Позвольте потоку контейнера выполнить подтверждение и запустить бизнес-задачу в потоке MessageListener. Если мой бизнес-запуск завершился неудачно, как сообщить контейнеру об отклонении сообщения? - person Tuscany; 07.07.2014
comment
После отладки кода я обнаружил, что контейнер отклонит сообщение, если я выброшу исключение в потоке MessageListener. Спасибо, Гэри Рассел. Моя проблема решена. - person Tuscany; 07.07.2014