Producers, Consumers & Brokers
BeginnerProducers publish messages to an exchange; the broker routes them to bound queues; consumers subscribe to queues and process messages, optionally acknowledging completion.
Overview
RabbitMQ follows the producer-broker-consumer model. Producers create and publish messages to exchanges — they never write directly to queues. The broker (RabbitMQ server) receives messages, routes them via exchange bindings, stores them in queues, and delivers them to consumers. Consumers subscribe to queues via push (basicConsume) or poll (basicGet). Each consumer runs in a channel thread and acknowledges processed messages — the broker removes a message from the queue only after it receives the acknowledgement.
Producer Flow
A producer opens a Channel on the TCP Connection, declares its exchange (idempotent), and calls basicPublish with an exchange name, routing key, and message body. Spring AMQP abstracts this via RabbitTemplate.
// Spring Boot producer — complete flow
@Configuration
public class RabbitConfig {
@Bean
public TopicExchange ordersExchange() {
return ExchangeBuilder.topicExchange("orders")
.durable(true).build();
}
@Bean
public MessageConverter jsonConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory cf,
MessageConverter converter) {
RabbitTemplate t = new RabbitTemplate(cf);
t.setMessageConverter(converter);
t.setConfirmCallback((cd, ack, cause) -> {
if (!ack) log.error("Publish NACK: {}", cause);
});
return t;
}
}
@Service
public class OrderProducer {
private final RabbitTemplate rabbitTemplate;
public void publishOrderPlaced(OrderEvent event) {
// exchange="orders", routingKey="order.placed", body=JSON(event)
rabbitTemplate.convertAndSend("orders", "order.placed", event);
}
}Consumer Flow
Consumers subscribe to queues and receive messages via push delivery. Spring AMQP creates a SimpleMessageListenerContainer that runs consumer threads per queue. Each thread calls the @RabbitListener method and acks after successful return.
@Component
public class OrderConsumer {
// Push-based consumer — Spring AMQP manages the listener container
@RabbitListener(queues = "order-processor",
concurrency = "2-5", // 2 to 5 consumer threads
ackMode = "AUTO") // ack on return, nack on exception
public void processOrder(OrderEvent event) {
log.info("Processing order {}", event.getOrderId());
inventoryService.reserve(event.getItems());
// AUTO ack: basicAck sent automatically after this method returns
// On exception: basicNack sent → message requeued or DLX'd
}
// Manual ack for fine-grained control
@RabbitListener(queues = "critical-orders", ackMode = "MANUAL")
public void processCritical(OrderEvent event, Acknowledgment ack,
Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG) long tag)
throws IOException {
try {
orderService.processWithCompensation(event);
ack.acknowledge(); // basicAck(tag, false)
} catch (RetryableException e) {
channel.basicNack(tag, false, true); // requeue=true
} catch (FatalException e) {
channel.basicNack(tag, false, false); // requeue=false → DLX
}
}
}Broker Responsibilities
The broker receives, routes, stores, and delivers messages. It tracks which messages are acknowledged and requeues unacked messages when a consumer channel closes. The management plugin exposes real-time stats.
// Broker responsibilities summary:
//
// 1. Accept TCP connections from producers and consumers
// 2. Authenticate (username/password, TLS cert, OAuth2 token)
// 3. Route messages via exchange bindings
// 4. Store messages in durable queues (to disk for persistent messages)
// 5. Deliver messages to subscribed consumers (push model)
// 6. Track unacked messages (delivery tag book-keeping)
// 7. Redeliver unacked messages when consumer channel closes
// 8. Apply TTL / queue limits / dead-lettering
// Verify broker connection and queue status (CLI)
rabbitmqctl list_queues name messages consumers
// name messages consumers
// order-processor 0 3
// order-audit 42 1 ← backlog building up
// Monitoring via HTTP API
curl -u admin:pass http://localhost:15672/api/queues/%2F/order-processor | \
jq '{messages, consumers, message_stats}'Key Points to Remember
- 1Producers publish to exchanges — never directly to queues.
- 2The broker routes messages from exchanges to queues via binding rules.
- 3Consumers subscribe to queues; the broker pushes messages to them.
- 4A message stays in the queue until the consumer sends basicAck.
- 5Unacked messages are redelivered when the consumer channel closes.
- 6Spring AMQP AUTO ack mode: ack on return, nack on exception (requeues by default).
Interview Questions
Sign in to ask AriaWhat is the role of the broker in RabbitMQ?
What happens to an unacknowledged message when the consumer channel closes?
What is the difference between basicAck and basicNack?
How does Spring AMQP AUTO ack mode handle exceptions in @RabbitListener?
Can a producer publish directly to a queue without an exchange? Explain.
Ask Aria about Producers, Consumers & Brokers
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.