RabbitMQ Architecture
RabbitMQ Architecture
RabbitMQ is a message broker implementing AMQP (Advanced Message Queuing Protocol).
Core Components
RabbitMQ Architecture:
Producer → Exchange → Binding → Queue → Consumer
┌─────────────────────────────────────────────────┐
│ RabbitMQ Broker │
│ │
│ Producer → [Exchange] → [Queue 1] → Consumer 1 │
│ ↗ ↘ [Queue 2] → Consumer 2 │
│ Producer → [Exchange] │
│ ↘ ↗ [Queue 3] → Consumer 3 │
│ Producer → [Exchange] │
└─────────────────────────────────────────────────┘
Key Concepts
| Component | Description |
|---|---|
| Producer | Publishes messages |
| Exchange | Routes messages to queues |
| Binding | Rule connecting exchange to queue |
| Queue | Stores messages |
| Consumer | Reads messages |
Message Flow
1. Producer publishes message to Exchange
2. Exchange routes message based on:
- Exchange type
- Routing key
- Bindings
3. Message lands in matching queue(s)
4. Consumer pulls/pushes from queue
5. Consumer acknowledges message
6. Message deleted from queue
Exchanges
RabbitMQ Exchange Types
Exchange Types Overview
1. Direct Exchange:
Routing key exactly matches binding key
Producer → Exchange (routing key: "order")
→ Queue "order-queue" (binding: "order")
2. Fanout Exchange:
Broadcasts to ALL bound queues (ignores routing key)
Producer → Exchange → Queue 1
→ Queue 2
→ Queue 3
3. Topic Exchange:
Pattern matching on routing key
"order.created" matches "order.*"
"order.created" matches "*.created"
4. Headers Exchange:
Matches message headers (not routing key)
Exchange Configuration
import pika
# Connect to RabbitMQ
connection = pika.BlockingConnection(
pika.ConnectionParameters('localhost')
)
channel = connection.channel()
# 1. Direct Exchange
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
channel.queue_declare(queue='direct_queue')
channel.queue_bind(
exchange='direct_logs',
queue='direct_queue',
routing_key='error' # Only messages with this key
)
# 2. Fanout Exchange
channel.exchange_declare(exchange='fanout_logs', exchange_type='fanout')
channel.queue_declare(queue='fanout_queue_1')
channel.queue_declare(queue='fanout_queue_2')
channel.queue_bind(exchange='fanout_logs', queue='fanout_queue_1')
channel.queue_bind(exchange='fanout_logs', queue='fanout_queue_2')
# 3. Topic Exchange
channel.exchange_declare(exchange='topic_logs', exchange_type='topic')
channel.queue_declare(queue='topic_queue')
channel.queue_bind(
exchange='topic_logs',
queue='topic_queue',
routing_key='order.*' # Matches order.created, order.updated
)
When to Use Each
| Exchange | Use Case | Example |
|---|---|---|
| Direct | Exact routing | Log levels (error, warning, info) |
| Fanout | Broadcasting | Live updates to multiple services |
| Topic | Flexible routing | Event types (order., user.) |
| Headers | Attribute-based | Priority-based routing |
Routing Keys
RabbitMQ Routing Keys
Routing Key Patterns
Direct Exchange:
- Exact match: "error" matches "error"
- No wildcards
Topic Exchange:
- * matches exactly one word: "order.*" matches "order.created"
- # matches zero or more words: "order.#" matches "order.created.v2"
Examples:
"order.created" → matches "order.*", "*.created", "order.created"
"user.email.updated" → matches "user.*.updated", "user.#"
Routing Example
# Topic exchange with routing patterns
channel.exchange_declare(exchange='events', exchange_type='topic')
# Bind queues with patterns
channel.queue_bind(
exchange='events',
queue='all-orders',
routing_key='order.#' # All order events
)
channel.queue_bind(
exchange='events',
queue='all-created',
routing_key='*.created' # All create events
)
channel.queue_bind(
exchange='events',
queue='order-created',
routing_key='order.created' # Exact match
)
# Publish messages
channel.basic_publish(
exchange='events',
routing_key='order.created',
body='{"order_id": 123}'
)
# Matches: all-orders, all-created, order-created
channel.basic_publish(
exchange='events',
routing_key='order.cancelled',
body='{"order_id": 456}'
)
# Matches: all-orders only
Best Practices
- Use meaningful routing keys:
entity.action(e.g.,order.created) - Keep hierarchy consistent:
service.entity.event - Use topic exchange for flexibility
- Document routing patterns for team clarity
- Monitor queue depths for routing issues
Practice Problems
Design a scalable RabbitMQ system. Cover high-level architecture, data model, and API design.
Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliabilityHow would you scale RabbitMQ to handle 10x the current load? Identify bottlenecks and solutions.
Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decompositionAnalyze potential failure modes for RabbitMQ and design mitigation strategies.
Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradationQuiz
1. What is the role of an exchange in RabbitMQ?
2. Which exchange type broadcasts to all bound queues?
3. In topic exchange, what does '#' match?
4. What pattern would match 'order.created' and 'order.cancelled'?
5. What happens after a consumer acknowledges a message?
Flashcards
Question
What are RabbitMQ exchange types?
Click to reveal answer
Answer
1) Direct (exact match), 2) Fanout (broadcast), 3) Topic (pattern match), 4) Headers (attribute match)
Question
Topic exchange wildcards?
Click to reveal answer
Answer
* matches exactly one word, # matches zero or more words in routing key
Question
Direct vs Fanout exchange?
Click to reveal answer
Answer
Direct: routes based on exact routing key match. Fanout: broadcasts to all bound queues.
Question
What is a binding in RabbitMQ?
Click to reveal answer
Answer
A rule connecting an exchange to a queue, optionally with a routing key pattern
Question
RabbitMQ vs Kafka: Key difference?
Click to reveal answer
Answer
RabbitMQ: message broker with routing, queue management. Kafka: distributed log with partitioning and replay.
Revision Notes
Key Takeaways
- 1.RabbitMQ uses exchanges to route messages to queues
- 2.Four exchange types: Direct, Fanout, Topic, Headers
- 3.Topic exchange provides flexible pattern-based routing
- 4.Routing key patterns: * (one word), # (zero or more words)
- 5.Choose RabbitMQ for routing needs, Kafka for log streaming
Interview Tips
- •Explain exchange types and when to use each
- •Demonstrate topic routing patterns with examples
- •Compare RabbitMQ vs Kafka architecture
- •Discuss message acknowledgment and delivery guarantees
Cheat Sheet
Cheat Sheet: RabbitMQ
Architecture
Producer → Exchange → Binding → Queue → Consumer
Exchange Types
- Direct: Exact routing key match
- Fanout: Broadcast to all queues
- Topic: Pattern matching (*, #)
- Headers: Attribute matching
Routing Key Patterns
- order.* → order.created, order.cancelled
- order.# → order.created, order.created.v2
- *.created → order.created, user.created
When to Use
- Direct: Log levels, exact routing
- Fanout: Broadcasting events
- Topic: Flexible event routing
- RabbitMQ vs Kafka: Routing vs Log replay