Queue

Queues are the place where the messages get stored. After producer posts a message to the exchange, it’s routed to the queues if the binding key matches to the routing or the header matches with the header. There is no type of queues. But, bear in mind that all the queues are bound to the nameless/default direct exchange with the routing key of the queue’s own name. That means if a message is sent to default exchange having a routing of the any queue’s name, then the queue will receive that message. All the queues must have a name and routing key (depending on exchange it binds to).

Properties

durable — Used by both the exchange and the queues. Means the queue and exchange survive if the rabbitmq restarts.

auto_delete — Used by both the exchange and the queues. Means if no queue is bound to any exchange then the exchange will be deleted. Like that if no consumer is bound to the queue, then the queue will be deleted automatically.

internal — Used by Exchange. If an exchange is internal, no client will be able to publish to the exchange. Only for an exchange to exchange binding.

alternate-exchange — Used by Exchange. If a message can not be routed to any bound queues (for any reason), the message will then be redirected to that specified exchange.

exclusive — Used by Queue. Only the current connection can use the queue. As soon as the connection goes off, the queue will be deleted.

x-message-ttl — Used by Queue. Sets TTL for a message that arrives. Messages will be moved from the queue after expires the TTL. In milliseconds.

x-expires — Used by Queue. Determines how many milliseconds the queue can be left unused before it’s deleted automatically.

x-max-length — Used by Queue. A max number of received messages can be stored before it starts dropping from its head.

x-queue-mode — Used by Queue. Default is “default”. If set “lazy”, then it’ll set the messages to the disk as much as possible to reduce the RAM usage.

delivery_mode — Used by Message. Persistent, Nonpersistent. Determines if can survive after server restart.

application_headers — Used by Message. Passed along with the message. These are used by the exchange on headers exchange.

QoS

The QoS means Quality of Service. In rabbitmq, if you’re asking for messages from queues and you have set “no ack” to true, which will let queues to delete the message as soon as you receive it. Even if your application crashes and the message is not handled properly, the message will be deleted for forever. But, by defining the QoS before you start to consume messages from a queue, using a number like 5 (as for an example called prefetch_count), you’re declaring that you should not be given more than 5 unacknowledged messages on the same channel your consumers are connected to. If you can’t acknowledge any of those given messages, you’ll no longer be given any new message to process. As soon as you acknowledge the queue that you’ve processed the message, it’ll then start sending you new messages till you reach that prefetch_count. To acknowledge the delivery, you must have to notify via the same channel they were received. Types of acknowledgments.

ack — Positive acknowledgment. Instructs RabbitMQ that the message can be discarded.

reject — Negative acknowledgment. Like positive ack, it’ll delete the message.

nack — Negative acknowledgment. Should not delete the message.

If a message is not acknowledged by the consumer, it’ll automatically be requeued when the channel or connection on which the delivery happened is closed.

Again, remember that the QoS is set on a channel level.

Things you should know

Whenever you publish a message, it goes to the exchange. Not in any queue. There is no need to declare a queue while publishing. (Not needed means, you don’t need to consider queue while publishing a message. It’s not required.).

From producer to exchange

To consume a message, a queue is bound to an exchange. A consumer consumes messages from a queue. That means you should first bind a queue to an exchange and then you can only consume a message. For default exchange (nameless exchange) you cannot bind a queue to that exchange. It’ll be sent directly whenever it finds the routing_key == queue_name.

Message from exchange to queue to consumer

RabbitMQ dispatches the messages to its consumer in a round-robin fashion. On average all the consumers will get almost the same amount of messages. That’s why you saw in figures that consumers of the same queue with multiple consumers received half of the messages each.

If you have multiple queues with the same routing key, you’ll get the same message in both the queues. You’ll not get those messages in round-robin fashion. Because round-robin only works while consuming messages. Not from exchange to queues.

If no queue is bound to exchange and by that time a message is sent to that exchange. Or a message with a routing key is sent to exchange and no queue is using that key to bind to that exchange. In both cases, the message will be lost. But, to overcome it, we can use alternate-exchange (AE) which will send the message to the defined queue in these scenarios. This argument must be set during the creation of an exchange.

(AE) which will send the message to the defined queue in these scenarios. This argument must be set during the creation of an exchange. If the queue is holding any message and no one is listening, then if the queue is about to delete the message (TTL, Drop from the head), then these messages can be sent to a Dead Letter Exchange (DLX). It’s an argument you need to set while creating the queue.

(DLX). It’s an argument you need to set while creating the queue. If a persistent message is sent to a non-durable queue, the message will no longer be persistent.

That’s it. This is what I found and came to know about while learning RabbitMQ.

Questions

I just came to know the following aroused in people’s mind. So, the questions and the answers are given below

Q: What are the mailing address & office address in the example?

The mailing address is that address you put on the envelope which is the destination/office address.

Q: What is a channel?

The channel was not included in the terminologies section before. It’s been added now. When your application communicates with RabbitMQ, it uses a connection (also added on terminologies). A channel is kind of a pipe through which these data/streams are passed through.

Q: I understand UCL is a queue but what is UCL.TWO?

Just like ucl , the ucl.two is also a queue. You can have multiple queues of the same routing key. If you have multiple (N) queues for the same routing key, you’ll receive identical messages to all those N queues. That is why ucl and ucl.two receives the same amount of messages.

Q: Why UCL had two consumers and others had one consumer only?

A: It’s all about how you want to develop the application. Suppose your queue receives too many messages and to keep your queue short you may need to add multiple consumers. If the volume of messages is not that high and one consumer can clean up that queue messages easily you’re good to use one consumer. So, it’s up to you how many consumers you want to your queue.

Finally, a Github repository is created for this purpose. Readme says how to install it. It’s in PHP. Read it, play with our preferred language.

Happy Coding. ❤

Edits: