Implementing Messaging with RabbitMQ
1. Adding RabbitMQ Dependencies
Example: RabbitMQ AMQP dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2. Configuring RabbitMQ Connection Properties
| Property | Default |
|---|---|
spring.rabbitmq.host |
localhost |
spring.rabbitmq.port |
5672 |
spring.rabbitmq.username |
guest |
spring.rabbitmq.password |
guest |
spring.rabbitmq.virtual-host |
/ |
spring.rabbitmq.ssl.enabled |
false |
spring.rabbitmq.publisher-confirm-type |
correlated |
3. Creating RabbitTemplate for Sending Messages
Example: Publish message with RabbitTemplate
@Service
public class OrderPublisher {
private final RabbitTemplate rabbit;
public OrderPublisher(RabbitTemplate rabbit) { this.rabbit = rabbit; }
public void publish(OrderPlaced evt) {
rabbit.convertAndSend("orders.exchange", "order.placed", evt);
}
}
4. Defining Queues, Exchanges, and Bindings
Example: Declare queue, exchange, and binding
@Configuration
public class RabbitConfig {
@Bean Queue ordersQueue() { return QueueBuilder.durable("orders.q").build(); }
@Bean TopicExchange ordersExchange() { return new TopicExchange("orders.exchange"); }
@Bean Binding bind(Queue q, TopicExchange ex) {
return BindingBuilder.bind(q).to(ex).with("order.*");
}
}
| Exchange Type | Routing |
|---|---|
| direct | Exact key match |
| topic | Wildcards (* and #) |
| fanout | Broadcast to all bindings |
| headers | Header attribute match |
5. Sending Messages to Queues (convertAndSend)
Example: Send message with headers and TTL
rabbit.convertAndSend("exchange", "routing.key", payload, msg -> {
msg.getMessageProperties().setHeader("X-Source", "orders-svc");
msg.getMessageProperties().setExpiration("60000");
return msg;
});
6. Creating Message Listeners (@RabbitListener)
Example: Consume messages with concurrency
@Component
public class OrderConsumer {
@RabbitListener(queues = "orders.q", concurrency = "4-10")
public void handle(OrderPlaced evt, @Header("X-Source") String source) {
/* process */
}
}
7. Configuring Message Converters (Jackson2JsonMessageConverter)
Example: Configure JSON message converter
@Bean MessageConverter jsonConverter() { return new Jackson2JsonMessageConverter(); }
@Bean RabbitTemplate rabbitTemplate(ConnectionFactory cf, MessageConverter mc) {
RabbitTemplate t = new RabbitTemplate(cf);
t.setMessageConverter(mc);
return t;
}
8. Handling Message Acknowledgments
| Mode | Behavior |
|---|---|
NONE |
Auto-ack on delivery (no redelivery) |
AUTO (default) |
Ack after listener returns; nack on exception |
MANUAL |
Listener calls channel.basicAck() |
9. Implementing Dead Letter Queues
Example: Dead letter queue configuration
@Bean Queue ordersQ() {
return QueueBuilder.durable("orders.q")
.withArgument("x-dead-letter-exchange", "orders.dlx")
.withArgument("x-dead-letter-routing-key", "orders.dead")
.withArgument("x-message-ttl", 30_000)
.build();
}
@Bean Queue dlq() { return QueueBuilder.durable("orders.dlq").build(); }
@Bean DirectExchange dlx() { return new DirectExchange("orders.dlx"); }
@Bean Binding dlBind() { return BindingBuilder.bind(dlq()).to(dlx()).with("orders.dead"); }
10. Using Message Properties and Headers
| Property | Use |
|---|---|
messageId |
Unique id for dedup |
correlationId |
Request/response correlation |
contentType |
Auto-set by converter |
expiration |
TTL (ms, string) |
priority |
0–9 (queue must support) |
headers |
Custom map |
11. Configuring Retry and Error Handling
Example: Retry with exponential backoff
spring:
rabbitmq:
listener:
simple:
retry:
enabled: true
initial-interval: 1s
max-attempts: 5
multiplier: 2
max-interval: 30s