RabbitMQ: How to specify the queue to publish to?

18,373

Solution 1

Basically queues can be binded to an exchange based on routingKeys.

Assume that you have 3 different publishers.
Publisher1 sending message to exchange with routingKey "events"
Publisher2 sending message to exchange with routingKey "tasks"
Publisher3 sending message to exchange with routingKey "jobs"

You can have a consumer that consumes only messages with specific routhingKey.
For example in order to have a consumer for "events" messages you declare like this

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

If you want to consume all the messages coming to the exchange you give the routing as '#'

So in short what i can say is,
1. Messages will be published to an exchange.
2. Queues will be bound to exchange based on routingKeys.
3. RabbitMQ will forward messages with matching routing keys to the corresponding queues.

Please see the tutorial - http://www.rabbitmq.com/tutorials/tutorial-three-java.html

The core idea in the messaging model in RabbitMQ is that the producer never sends any messages directly to a queue. Actually, quite often the producer doesn't even know if a message will be delivered to any queue at all. Instead, the producer can only send messages to an exchange

Solution 2

To expand on @Tien Nguyen's answer, there is a "cheat" in RabbitMQ that effectively lets you publish directly to a queue. Each queue is automatically bound to the AMQP default exchange, with the queue's name as the routing key. The default exchange is also known as the "nameless exchange" - ie its name is the empty string. So if you publish to the exchange named "" with routing key equal to your queue's name, the message will go to just that queue. It is going through an exchange as @John said, it's just not one that you need to declare or bind yourself.

I don't have the Java client handy to try this code, but it should work.

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

That said, this is mostly contrary to the spirit of how RabbitMQ works. For normal application flow you should declare and bind exchanges. But for exceptional cases the "cheat" can be useful. For example, I believe this is how the Rabbit Admin Console allows you to manually publish messages to a queue without all the ceremony of creating and binding exchanges.

Solution 3

please try this:

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

It worked for my project.

Share:
18,373
Admin
Author by

Admin

Updated on June 17, 2022

Comments

  • Admin
    Admin about 2 years

    RabbitMQ's Channel#basicConsume method gives us the following arguments:

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

    Giving us the ability to tell RabbitMQ exactly which queue we want to consume from.

    But Channel#basicPublish has no such equivalency:

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

    Why can't I specify the queue to publish to here?!? How do I get a Channel publishing to, say, a queue named logging? Thanks in advance!

  • Admin
    Admin almost 11 years
    Thanks @tien nguyen (+1) - However, it looks like you are using the basicPublish(java.lang.String exchange, java.lang.String routingKey, AMQP.BasicProperties props, byte[] body) overload of basicPublish. In that overload, the 2nd parameter (which you have as "yourQueueName" is called "routingKey". So, is "routingKey" RabbitMQ lingo for "queue name"?
  • Vishal John
    Vishal John almost 11 years
    @TicketMonster routingKey doesn't mean queue. A queue will be bound to an exchange based on routingKey and only will receive only messages which have that routingKey. see my answer.
  • Admin
    Admin almost 11 years
    Awesome @John (+1 and green check) - thanks for the helpful, thorough and informative answer!
  • robthewolf
    robthewolf almost 11 years
    in a bit more detail the message is sent to the default exchange so the routing key will in effect send to the queue. But no they are not equivalent
  • rkz_io
    rkz_io over 7 years
    Will this cheat work even if the queue is also bound to an exchange?
  • Brian Reischl
    Brian Reischl over 7 years
    Yes, it will, we have code that does this to queues that are bound to other exchanges.
  • Colin Nichols
    Colin Nichols about 7 years
    Amazing. Exactly what I needed for automated testing. thank you
  • user2864740
    user2864740 about 5 years
    This is also handy in a number of other scenarios outside of testing including local work queues and 'restoration' of messages, etc.