'RabbitMQ doesn't show me the queues and exchange created in my Spring consumer and publisher apps
I am trying to create a publisher and consumer apps in spring using RabbitMQ. Every thing works fine and when the publisher sends a message, the consumer receives it and consumes it successfully. But as you can see in the picture below, RabbitMQ interface doesn't show me the queues and exchange created.
No QUEUES
No Exchange
This is the code I wrote:
RABBITMQ CONFIGURATION (SAME IN PUBLISHER APP AND CONSUMER APP)
package com.example.rabbitmq.springrabbitmqconsumer.configuration;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
public static final String ROUTING_A = "routing.A";
public static final String ROUTING_B = "routing.B";
//QUEUES
@Bean
Queue queueA() {
return new Queue("queue.A", false);
}
@Bean
Queue queueB() {
return new Queue("queue.B", false);
}
//Direct Exchange
@Bean
DirectExchange exchange() {
return new DirectExchange("exchange.direct");
}
//BINDINGS
@Bean
Binding bindingA(Queue queueA, DirectExchange exchange) {
return BindingBuilder.bind(queueA)
.to(exchange)
.with(ROUTING_A);
}
@Bean
Binding bindingB(Queue queueB, DirectExchange exchange) {
return BindingBuilder.bind(queueB)
.to(exchange)
.with(ROUTING_B);
}
@Bean
MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter());
return rabbitTemplate;
}
}
MESSAGE MODEL ( SAME IN PUBLISHER AND CONSUMER APPS)
package com.example.rabbitmq.springrabbitmqconsumer.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Message {
private int id;
private String name;
}
CONSUMER CONTROLLER
package com.example.rabbitmq.springrabbitmqconsumer.controller;
import com.example.rabbitmq.springrabbitmqconsumer.model.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class Consumer {
@RabbitListener(queues = "queue.A")
private void receiveA(Message message) {
log.info("Message received from queueA -> {}", message);
}
@RabbitListener(queues = "queue.B")
private void receiveB(Message message) {
log.info("Message received from queueB -> {}", message);
}
}
PIBLISHER CONTROLLER
package com.example.rabbitmq.springrabbitmqproducer.contoller;
import com.example.rabbitmq.springrabbitmqproducer.model.Message;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Producer {
private final RabbitTemplate rabbitTemplate;
private final DirectExchange exchange;
public Producer(RabbitTemplate rabbitTemplate, DirectExchange exchange) {
this.rabbitTemplate = rabbitTemplate;
this.exchange = exchange;
}
@PostMapping("/posta")
public String senda(@RequestBody Message message) {
rabbitTemplate.convertAndSend(exchange.getName(), "routing.A", message);
return "message sent successfully";
}
@PostMapping("/postb")
public String sendb(@RequestBody Message message) {
rabbitTemplate.convertAndSend(exchange.getName(), "routing.B", message);
return "message sent successfully";
}
}
PROPERTIES FILE (SAME IN BOTH APPS EXCEPT THE PORT)
server.port=8081
#rabbitmq configuration
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
this is the docker command I used to start the RabbitMQ container:
docker run -d --name my-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
As you can see, the consumer receives the message and consumes it
Solution 1:[1]
I have just remembered that i asked this question and i forgot to answer it
so here is the solution.
I found out that rabbitmq was installed in my pc and that caused a confusion it seems like. Because, Spring run the rabbitmq instance automatically the same way it does with tomcat so when i ran a rabbitmq docker image, spring was using the local instance instead of the docker image.
I only realised that when i dockerised my spring app and i the rabbitmq management UI start registering the queues.
Conclusion
If u have rabbitmq installed locally in ur pc this is some scenarios that may happens:
1/non dockeried spring app: works fine bcz spring will use the local rabbitmq instance by default, and u can open the management UI
2/dockerised spring app + rabbitmq docker image: works fine, bcz when u dockerise ur spring app it will stop using the local instance
3/non dockeried spring app + rabbitmq docker image: WEIRD BEHAVIOUR, spring will continue on pushing messages to the queues just fine but when you try to open the management UI, you won't see any registered queue probably bcz thats the management UI of the docker image instance
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Haithem Nasri |