2013-08-30 3 views
5

RabbitMQ в Channel#basicConsume дает нам следующие аргументы:RabbitMQ: Как указать очередь для публикации? Метод

channel.basicConsume(queueName, autoAck, consumerTag, noLocal, 
    exclusive, arguments, callback); 

дает нам возможность сказать RabbitMQ точно в какую очередь мы хотим потреблять от.

Но Channel#basicPublish не имеет такой эквивалентности:

channel.basicPublish(exchangeName, routingKey, mandatory, immediateFlag, 
    basicProperties, messageAsBytes); 

Почему я не могу указать очереди публиковать сюда?!? Как получить публикацию Channel, скажем, в очереди с именем logging? Спасибо заранее!

+1

Что вы хотите сделать, можно сделать с помощью эксклюзивной очереди, с прямым обменом и известным именем очереди, а также с определенным ключом маршрута + обмен темой. – pinepain

+0

Спасибо @ zaq178miami (+1) - можете ли вы представить пример кода? –

ответ

13

В основном очереди могут быть привязаны к обмену на основе routingKeys.

Предположим, что у вас есть 3 разных издателя.
Publisher1 отправки сообщения для обмена с routingKey «события»
Publisher2 посылая сообщение для обмена с routingKey «задачи»
Publisher3 посылая сообщение для обмена с routingKey «рабочих мест»

Вы можете иметь потребитель, который потребляет только сообщения с определенным маршрутированием.
Например, чтобы иметь потребителя для «событий» сообщений вы объявляете как этот

channel.queueBind(queueName, exchangeName, "events"); 

Если вы хотите, чтобы потреблять все сообщения, поступающие на биржу вы даете Routing как «#»

Короче говоря, я могу сказать,
1. Сообщения будут опубликованы на бирже.
2. Очереди будут обязаны обмениваться на основе routingKeys.
3. RabbitMQ пересылает сообщения с соответствующими ключами маршрутизации в соответствующие очереди.

Пожалуйста, смотрите учебник - http://www.rabbitmq.com/tutorials/tutorial-three-java.html

Основная идея в модели обмена сообщениями в RabbitMQ является то, что производитель никогда не посылает сообщения непосредственно в очередь. Собственно, нередко производитель даже не знает, будет ли сообщение доставлено в любую очередь вообще. Вместо этого производитель может отправлять сообщения только на обмен

+0

Awesome @John (+1 и зеленый чек) - спасибо за полезный, тщательный и информативный ответ! –

0

пожалуйста, попробуйте следующее:

channel.basicPublish("", yourQueueName, null, 
     message.getBytes((Charset.forName("UTF-8")))); 

Он работал для моего проекта.

+1

Спасибо @tien nguyen (+1) - Однако похоже, что вы используете ['basicPublish (обмен java.lang.String, java.lang.String routingKey, AMQP.BasicProperties реквизит, byte [] body)'] (http://www.rabbitmq.com/releases/rabbitmq-java-client/v1.7.2/rabbitmq-java-client-javadoc-1.7.2/com/rabbitmq/client/Channel.html#basicPublish%28java.lang. String,% 20java.lang.String,% 20com.rabbitmq.client.AMQP.BasicProperties,% 20byte []% 29) перегрузка 'basicPublish'. В этой перегрузке второй параметр (который у вас есть как «yourQueueName» называется «routingKey». Итак, «routingKey» RabbitMQ lingo для «queue name»? –

+0

@TicketMonster routingKey не означает очередь. Очередь будет связана к обмену на основе routingKey и только получит только сообщения, которые имеют этот routingKey.Подробнее мой ответ –

+0

сообщение отправлено на обмен по умолчанию, поэтому ключ маршрутизации будет по сути отправлен в очередь. не эквивалентны – robthewolf

10

Чтобы расширить ответ на ответ @Tien Nguyen, в RabbitMQ есть «чит», который эффективно позволяет публиковать непосредственно в очереди. Каждая очередь автоматически привязана к обмену по умолчанию AMQP, причем имя очереди в качестве ключа маршрутизации. Обмен по умолчанию также известен как «безымянный обмен», то есть его имя является пустой строкой. Поэтому, если вы публикуете на бирже с именем "" с ключом маршрутизации, равным имени вашей очереди, сообщение отправляется только в эту очередь. Он проходит через обмен, как сказал Джонсон, это просто не то, что вам нужно объявить или связать себя.

У меня нет Java-клиента, который может попробовать этот код, но он должен работать.

channel.basicPublish("", myQueueName, false, false, null, myMessageAsBytes); 

Это говорит о том, что это в основном противоречит духу того, как работает RabbitMQ. Для нормального потока приложений вы должны объявлять и связывать обмены. Но в исключительных случаях «чит» может быть полезен. Например, я считаю, что Rabbit Admin Console позволяет вручную публиковать сообщения в очереди без всякой церемонии создания и связывания обменов.

+0

Будет ли этот чит работать, даже если очередь также привязана к обмену? –

+0

Да, это будет, у нас есть код что делает это для очередей, связанных с другими обменами. –

+0

Удивительно. То, что мне нужно для автоматического тестирования. –

Смежные вопросы