Before we start, I expect you’ve understood what RabbitMQ is, what it does, and what exchange, queue, binding, and routing keys are. Well, let’s begin.
There are two apps built for this article, they are called rabbitmq-producer and rabbitmq-consumer. Both apps are written in Java Spring Boot.
The Application Scheme
From the scheme above, you can see that:
Direct Exchange is bound to Queue A with direct1 routing key.
Direct Exchange is bound to Queue B with direct2 routing key.
Topic Exchange is bound to Queue C with rabbitmq.# routing key.
Topic Exchange is bound to Queue D with rabbitmq.spring.# routing key.
Fanout Exchange is bound to Queue Ewithout routing key (because fanout exchange doesn’t need one).
Fanout Exchange is bound to Queue Fwithout routing key (because fanout exchange doesn’t need one).
Inside application.properties
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
exchange.direct=direct-exchange
exchange.topic=topic-exchange
exchange.fanout=fanout-exchange
queue.A=queue-A
queue.B=queue-B
queue.C=queue-C
queue.D=queue-D
queue.E=queue-E
queue.F=queue-F
routing.direct.1=direct1
routing.direct.2=direct2
routing.topic.rabbitmq.#=rabbitmq.#
routing.topic.rabbitmq.spring.#=rabbitmq.spring.#
Direct Exchange
Direct Exchange is an exchange that forwards messages to queues based on the messages’ routing key. Take a look at the rabbitmq-producer’s code below.
@Value("${routing.direct.1}")
private String direct1RoutingKey;
@Bean
public Binding bindingDirectExchangeQueueADirect1(DirectExchange directExchange, Queue queueA) {
return BindingBuilder.bind(queueA).to(directExchange).with(direct1RoutingKey);
}
@Value("${routing.direct.2}")
private String direct2RoutingKey;
@Bean
public Binding bindingDirectExchangeQueueBDirect2(DirectExchange directExchange, Queue queueB) {
return BindingBuilder.bind(queueB).to(directExchange).with(direct2RoutingKey);
}
Both codes are all about binding the direct-exchange with queue A with direct1 routing key and queue B with direct2 routing key.
So, when the producer sends a message to direct-exchange with direct1 routing key, it’ll be sent to queue A.
Sending a message to direct-exchange with direct1 routing key via API endpoint with Postman
See the log from rabbitmq-consumer below.
Message received in Queue A : message to direct-exchange with direct1 routing key
When the producer sends a message to direct-exchange with direct2 routing key, it’ll be sent to queue B.
Sending a message to direct-exchange with direct1 routing key via API endpoint with Postman.
See the log from rabbitmq-consumer below.
Message received in Queue B : message to direct-exchange with direct2 routing key
Topic Exchange
Topic exchange is the same as direct exchange, but the routing key here is also called routing pattern because the routing key is not fixed. Instead, it uses wildcards. Take a look at the rabbitmq-producer’s code below.
@Value("${routing.topic.rabbitmq.#}")
private String topicRabbitMQRoutingKey;
@Bean
public Binding bindingTopicExchangeQueueCTopicRabbitMQ(TopicExchange topicExchange, Queue queueC) {
return BindingBuilder.bind(queueC).to(topicExchange).with(topicRabbitMQRoutingKey);
}
@Value("${routing.topic.rabbitmq.spring.#}")
private String topicRabbitMQSpringRoutingKey;
@Bean
public Binding bindingTopicExchangeQueueDTopicRabbitMQSpring(TopicExchange topicExchange, Queue queueD) {
return BindingBuilder.bind(queueD).to(topicExchange).with(topicRabbitMQSpringRoutingKey);
}
The first code is the binding between topic-exchange with queue C with rabbitmq.# routing pattern. For example, routing key rabbitmq.learning, rabbitmq.spring.learning, and rabbitmq.learning.exchange matches that pattern.
The second code is the binding between topic-exchange with queue D with rabbitmq.spring.# routing pattern. For example, routing key rabbitmq.spring.learning and rabbitmq.spring.learning.exchange matches that pattern.
Suppose we want to send a message with rabbitmq.learning routing key.
The message will be sent to queue C.
Message received in Queue C : message to topic-exchange with rabbitmq.learning routing key
If we want to send a message with rabbitmq.spring.learning routing key:
The message will be sent to queue C and queue D.
Message received in Queue C : message to topic-exchange with rabbitmq.spring.learning routing key
Message received in Queue D : message to topic-exchange with rabbitmq.spring.learning routing key
Fanout Exchange
The main difference between fanout exchange and the other exchanges is that fanout exchange doesn’t need routing key to forward messages to queues. Fanout exchange will forward messages to every queue bound to it. Take a look at the code below.
@Bean
public Binding bindingFanoutExchangeQueueEFanout(FanoutExchange fanoutExchange, Queue queueE) {
return BindingBuilder.bind(queueE).to(fanoutExchange);
}
@Bean
public Binding bindingFanoutExchangeQueueFFanout(FanoutExchange fanoutExchange, Queue queueF) {
return BindingBuilder.bind(queueF).to(fanoutExchange);
}
The first code is the binding between fanout-exchange with queue E. The second code is the binding between fanout-exchange with queue F. As you can see, there is no routing key specified in the binding process.
When we send a message to fanout-exchange, the message will be forwarded to queue E and queue F.
Here is the log in rabbitmq-consumer.
Message received in Queue E : message to fanout-exchange
Message received in Queue F : message to fanout-exchange
That’s It!
That’s all about exchange types in RabbitMQ. The complete source code can be found here .
Comments