Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RabbitMq : Create queue dynamically

I have a scenario where I want to publish some messages to rabbitmq-exchange using a specific routing key for eg. abc

The issue is there may already be any queue already binded with routing key "abc" or may be not. The behavior for such scenarios seem to be either drop that message or if a dead letter exchange is configured, it will be routed to dead letter exchange.

I want to dynamically create a queue with same name as the routing key i.e. "abc" if no queue is present for that routing key instead of dropping or sending it to DLX.

Is there any known way to do the same?

like image 333
Rahul Avatar asked Apr 10 '15 11:04

Rahul


2 Answers

From my research, I'm not aware of a way to configure the server side to create queues dynamically. However, you could do this on the client side to achieve the same effect:

Implement a ReturnListener on the channel to listen for unroutable messages. Look at the "Handling Unroutable Messages" section on this page for an example:

https://www.rabbitmq.com/api-guide.html

Then, you can use the routingKey that's passed into the handler to create a queue with the same name, using the queueDeclare() and queueBind() methods (see "Using exchanges and queues" on the same link for an example).

like image 172
GeekChick Avatar answered Oct 04 '22 00:10

GeekChick


There is no afaik defaut behaviour for your case. You could create a plugin or you could rely on client logic which are the purpose of my answer.

It is important to know that RabbitMQ queue declare/bind is an idempotent operation

Declare queue, create if needed.This method creates or checks a queue. When creating a new queue the client can specify various properties that control the durability of the queue and its contents, and the level of sharing for the queue.

hypothesis 1 : queues cannot be deleted or queues can be deleted but clients will know it, the queue set can fit in memory

Each client maintains a set of queues. Before sending a message, the client checks if the set contains the queue. If not it declares and binds the queue and put the queue into the set.

At bootstrap, the queues set can be initialized with the existing queues using for example the HTTP API (eg. a java client)

How to do it depends on your RabbitMQ client. For example using spring-amqp, you can extend and override RabbitTemplate#doSend

hypothesis 2: queues can be deleted and clients will not know

As suggested by GeekChick you can register a ReturnListener. All message must be send with the mandatory flag

hypothesis 3: I don't mind the cost of declare/bind queue*

You always, prior of sending a message, declare and bind the queue. AFAIK the cost, once created, should be more or less equals to the network footprint + map lookup.

like image 41
Nicolas Labrot Avatar answered Oct 04 '22 01:10

Nicolas Labrot