[rabbitmq-discuss] Create exchanges and queues beforehand

Marek Majkowski majek04 at gmail.com
Mon Nov 14 15:34:58 GMT 2011


On Mon, Nov 14, 2011 at 12:22, Stefano Ghio <steghio at eng.it> wrote:
> I was fiddling with the Topic examples and I ran into a problem. If I start
> the client "ReceiveLogsTopic" before the sender "EmitLogTopic" I see
> everything working fine. Sender sends and client receives and displays
> right.
>
> However, if I start the sender before the client, the message gets sent but
> then nothing happens, the queue appears to be empty and the client keeps
> waiting for nothing.

Yes. RabbitMQ doesn't store 'old' messages. After the queue
is created only 'new' messages will go to it.

If you need to hear about previous messages, you should
create queue beforehand.

If you can't do it (you don't know about consumers while
you're sending messages), you probably have it solved
in an application layer - store data in a database
and query it after the queue was created.
(beware race conditions there)

> I think that's correct since the queue is created at runtime and is
> destroyed when there's nothing more to do with it as explained in the
> documentation:
>
> channel.exchangeDeclare(exchangeName, "direct", true);
> String queueName = channel.queueDeclare().getQueue();
> channel.queueBind(queueName, exchangeName, routingKey);
>
> This will actively declare the following objects, both of which can be
> customised by using additional parameters. Here neither of them have any
> special arguments.
>
> a durable, non-autodelete exchange of "direct" type
> a non-durable, exclusive, autodelete queue with a generated name
>
> What I would like to do instead is (example):
>
> 1)
> create 3 exchanges: EXA, EXB and EXC
> for every exchange, create 2 queues and bind them to it: Q1 and Q2. All
> queues have the same name but are not the same object (see attached PNG if
> needed)

Nope. A queue is identified by a name. The same name= the same
queue. You can bind multiple exchanges to a queue though,
and receive data from multiple exchanges on a single queue.
(also, see some magical properties on received messages,
you should be able to get routing key and exchange name
per message)

> 2)
> send a message to be queued in queue Q1 through EXA
> send the same message to be queued in queue Q1 through EXB
> message then is queued in two different queues which happen to have the same
> name but are binded to different exchanges
> 3)
> poll Q1 through EXA to read messages and delete message
> poll Q1 through EXB to read messages and leave message there
> message then is no longer in EXA-Q1 but is still available through EXB-Q1
>
> I don't and can't know if and when someone will try to send or read
> messages.
>
> I guess it would require me to declare and bind a queue beforehand, maybe by
> using 3 classes: setUpExchangeAndQueues, sendMessage, pollMessages, but I'm
> a bit at loss here, could anyone point me in the right direction?
>
> I read that:
>
> If several clients want to share a queue with a well-known name, this code
> would be appropriate:
>
> channel.exchangeDeclare(exchangeName, "direct", true);
> channel.queueDeclare(queueName, true, false, false, null);
> channel.queueBind(queueName, exchangeName, routingKey);
>
> This will actively declare:
>
> a durable, non-autodelete exchange of "direct" type
> a durable, non-exclusive, non-autodelete queue with a well-known name
>
> Tried it but failed.
>
> Please advise, I'm going crazy on this.

Sorry, I'm not really following the last part.

Marek


More information about the rabbitmq-discuss mailing list