RabbitMQ Overview & Configuration Guide
Comprehensive guide to RabbitMQ - message broker for distributed systems, microservices, and event-driven architectures.
Table of Contents
- Introduction
- Architecture & Concepts
- Exchange Types
- Queue Configuration
- Message Routing Patterns
- Publisher-Consumer Patterns
- High Availability & Clustering
- Federation & Shovel
- Security & Authentication
- Monitoring & Management
- Client Libraries
- Kubernetes Deployment
- Performance Tuning
- Best Practices
- Troubleshooting
Introduction
What is RabbitMQ?
RabbitMQ is an open-source message broker implementing the Advanced Message Queuing Protocol (AMQP). It enables applications to communicate asynchronously through messages.
Key Features: - Reliable delivery - Persistence, acknowledgements, publisher confirms - Flexible routing - Multiple exchange types (direct, topic, fanout, headers) - Clustering - High availability and horizontal scaling - Multi-protocol - AMQP 0-9-1, AMQP 1.0, MQTT, STOMP - Management UI - Web-based monitoring and administration - Plugin ecosystem - Federation, Shovel, delayed messaging, consistent hash exchange
When to Use RabbitMQ?
Use Cases: - Microservices communication - Decouple services with async messaging - Event-driven architectures - Publish events, subscribe to topics - Task queues - Distribute work across workers (e.g., background jobs) - Real-time messaging - Chat applications, notifications - Data streaming - Ingest and process high-volume data streams - Request/Reply - RPC-style communication with correlation IDs
RabbitMQ vs Kafka
| Feature | RabbitMQ | Apache Kafka |
|---|---|---|
| Protocol | AMQP, MQTT, STOMP | Custom TCP protocol |
| Messaging Model | Push-based (broker pushes to consumers) | Pull-based (consumers poll) |
| Message Retention | Messages deleted after consumption | Messages retained for configurable period |
| Use Case | Task queues, RPC, complex routing | Event streaming, log aggregation |
| Ordering | Per-queue ordering | Per-partition ordering |
| Throughput | ~20K msgs/sec (single broker) | ~100K+ msgs/sec (cluster) |
| Latency | Low latency (<10ms) | Low latency (~5ms) |
| Message Size | Suitable for small-medium messages | Optimized for larger messages |
Recommendation: - RabbitMQ - Task distribution, RPC, complex routing, low-latency messaging - Kafka - Event sourcing, log aggregation, stream processing, high throughput
Architecture & Concepts
Core Components
Components:
- Producer (Publisher) - Application that sends messages
- Exchange - Routes messages to queues based on routing rules
- Queue - Buffer that stores messages until consumed
- Consumer - Application that receives messages
- Binding - Link between exchange and queue with routing key
- Routing Key - Address that exchange uses to route messages
- Virtual Host (vhost) - Logical grouping for isolation
Message Flow
1. Producer publishes message to Exchange with Routing Key
2. Exchange routes message to Queue(s) based on Binding rules
3. Message is stored in Queue until consumed
4. Consumer receives message from Queue
5. Consumer sends ACK (acknowledgement) to RabbitMQ
6. RabbitMQ deletes message from Queue
Virtual Hosts (vhosts)
Purpose: Logical separation of resources (exchanges, queues, users).
Use Cases: - Multi-tenancy - Isolate environments (dev, staging, prod) - Security - Separate permissions per vhost - Organization - Group resources by team or application
Example:
/prod - Production environment
/staging - Staging environment
/dev - Development environment
/team-alpha - Team Alpha's queues
CLI:
# Create vhost
rabbitmqctl add_vhost /prod
# List vhosts
rabbitmqctl list_vhosts
# Set permissions
rabbitmqctl set_permissions -p /prod myuser ".*" ".*" ".*"
Exchange Types
Exchanges route messages to queues based on routing keys and bindings.
1. Direct Exchange
Routing: Message delivered to queues whose binding key exactly matches the routing key.
Use Case: Unicast routing, point-to-point messaging.
Example:
Exchange: logs.direct
Binding: Queue "error_logs" -> routing key "error"
Binding: Queue "info_logs" -> routing key "info"
Publish with key "error" -> routed to "error_logs"
Publish with key "info" -> routed to "info_logs"
Python Example:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# Declare exchange
channel.exchange_declare(exchange='logs.direct', exchange_type='direct')
# Declare queues
channel.queue_declare(queue='error_logs')
channel.queue_declare(queue='info_logs')
# Bind queues
channel.queue_bind(exchange='logs.direct', queue='error_logs', routing_key='error')
channel.queue_bind(exchange='logs.direct', queue='info_logs', routing_key='info')
# Publish message
channel.basic_publish(exchange='logs.direct', routing_key='error', body='Critical error!')
2. Fanout Exchange
Routing: Message delivered to all queues bound to the exchange (ignores routing key).
Use Case: Broadcast messaging, pub/sub pattern.
Example:
Exchange: notifications.fanout
Binding: Queue "email_queue"
Binding: Queue "sms_queue"
Binding: Queue "push_queue"
Publish message -> routed to ALL three queues
Python Example:
# Declare fanout exchange
channel.exchange_declare(exchange='notifications.fanout', exchange_type='fanout')
# Bind multiple queues
channel.queue_bind(exchange='notifications.fanout', queue='email_queue')
channel.queue_bind(exchange='notifications.fanout', queue='sms_queue')
channel.queue_bind(exchange='notifications.fanout', queue='push_queue')
# Publish once, delivered to all queues
channel.basic_publish(exchange='notifications.fanout', routing_key='', body='New order!')
3. Topic Exchange
Routing: Message delivered to queues whose binding pattern matches the routing key.
Patterns:
- * - Matches exactly one word
- # - Matches zero or more words
Use Case: Multi-criteria routing, hierarchical messaging.
Example:
Exchange: events.topic
Binding: Queue "all_orders" -> pattern "order.*"
Binding: Queue "us_orders" -> pattern "order.us.#"
Binding: Queue "critical_only" -> pattern "*.*.critical"
Publish "order.us.created" -> routed to "all_orders", "us_orders"
Publish "order.eu.critical" -> routed to "all_orders", "critical_only"
Publish "payment.us.critical" -> routed to "critical_only"
Python Example:
# Declare topic exchange
channel.exchange_declare(exchange='events.topic', exchange_type='topic')
# Bind queues with patterns
channel.queue_bind(exchange='events.topic', queue='all_orders', routing_key='order.*')
channel.queue_bind(exchange='events.topic', queue='us_orders', routing_key='order.us.#')
channel.queue_bind(exchange='events.topic', queue='critical_only', routing_key='*.*.critical')
# Publish with routing keys
channel.basic_publish(exchange='events.topic', routing_key='order.us.created', body='Order #123')
channel.basic_publish(exchange='events.topic', routing_key='order.eu.critical', body='Critical order!')
4. Headers Exchange
Routing: Match based on message headers instead of routing key.
Use Case: Complex routing with multiple attributes.
Example:
# Declare headers exchange
channel.exchange_declare(exchange='tasks.headers', exchange_type='headers')
# Bind queue with header matching
channel.queue_bind(
exchange='tasks.headers',
queue='high_priority',
arguments={
'x-match': 'all', # all headers must match
'priority': 'high',
'region': 'us-east'
}
)
# Publish with headers
channel.basic_publish(
exchange='tasks.headers',
routing_key='',
body='Urgent task',
properties=pika.BasicProperties(
headers={'priority': 'high', 'region': 'us-east'}
)
)
Default Exchange
Name: "" (empty string)
Type: Direct exchange
Behavior: Routes messages to queues whose name matches the routing key.
Example:
# Publish to default exchange (directly to queue name)
channel.basic_publish(exchange='', routing_key='my_queue', body='Hello')
Queue Configuration
Queue Properties
| Property | Description | Default |
|---|---|---|
| Durable | Queue survives broker restart | False |
| Exclusive | Used by only one connection, deleted when closed | False |
| Auto-delete | Deleted when last consumer unsubscribes | False |
| TTL | Message time-to-live (milliseconds) | None |
| Max Length | Maximum messages in queue | None |
| Max Priority | Enable priority queuing (0-255) | None |
Durable Queues
Purpose: Persist queue metadata across broker restarts.
Note: Durable queues require persistent messages to survive restart.
Persistent Messages
Purpose: Messages survive broker restart.
channel.basic_publish(
exchange='',
routing_key='tasks',
body='Task data',
properties=pika.BasicProperties(
delivery_mode=2, # Persistent
)
)
Message TTL (Time-To-Live)
Per-Queue TTL:
Per-Message TTL:
channel.basic_publish(
exchange='',
routing_key='tasks',
body='Task data',
properties=pika.BasicProperties(
expiration='60000' # 60 seconds
)
)
Queue Length Limit
Purpose: Prevent unbounded queue growth.
channel.queue_declare(
queue='bounded_queue',
arguments={
'x-max-length': 10000,
'x-overflow': 'drop-head' # Drop oldest messages
}
)
Overflow Behaviors:
- drop-head - Drop oldest messages
- reject-publish - Reject new messages
- reject-publish-dlx - Reject and send to Dead Letter Exchange
Priority Queues
Purpose: Process high-priority messages first.
# Declare priority queue
channel.queue_declare(
queue='priority_tasks',
arguments={'x-max-priority': 10}
)
# Publish with priority
channel.basic_publish(
exchange='',
routing_key='priority_tasks',
body='Urgent task',
properties=pika.BasicProperties(priority=9)
)
Dead Letter Exchange (DLX)
Purpose: Route rejected or expired messages to another exchange.
channel.queue_declare(
queue='main_queue',
arguments={
'x-dead-letter-exchange': 'dlx.exchange',
'x-dead-letter-routing-key': 'failed'
}
)
Use Cases: - Retry logic (reprocess failed messages) - Error handling (log rejected messages) - Delayed processing (TTL + DLX)
Message Routing Patterns
1. Work Queue (Task Distribution)
Pattern: Distribute tasks among multiple workers.
Configuration:
- One queue, multiple consumers
- Round-robin distribution by default
- Use prefetch_count for fair dispatch
Example:
# Producer
channel.queue_declare(queue='tasks', durable=True)
channel.basic_publish(
exchange='',
routing_key='tasks',
body='Process order #123',
properties=pika.BasicProperties(delivery_mode=2)
)
# Consumer (multiple instances)
def callback(ch, method, properties, body):
print(f"Processing: {body}")
# Simulate work
time.sleep(5)
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=1) # Fair dispatch
channel.basic_consume(queue='tasks', on_message_callback=callback)
channel.start_consuming()
2. Publish/Subscribe (Fanout)
Pattern: Broadcast messages to all subscribers.
Configuration: - Fanout exchange - Each subscriber has its own queue
Example:
# Publisher
channel.exchange_declare(exchange='logs', exchange_type='fanout')
channel.basic_publish(exchange='logs', routing_key='', body='Log message')
# Subscriber 1
channel.queue_declare(queue='', exclusive=True)
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='logs', queue=queue_name)
3. Routing (Direct Exchange)
Pattern: Route messages based on severity/category.
Example:
# Route error logs to error queue, info logs to info queue
channel.exchange_declare(exchange='logs.direct', exchange_type='direct')
# Bind queues
channel.queue_bind(exchange='logs.direct', queue='error_logs', routing_key='error')
channel.queue_bind(exchange='logs.direct', queue='info_logs', routing_key='info')
# Publish
channel.basic_publish(exchange='logs.direct', routing_key='error', body='Critical error!')
4. Topics (Pattern Matching)
Pattern: Route based on multi-criteria (e.g., region.service.level).
Example:
# Routing: <region>.<service>.<level>
# us.orders.critical -> US critical orders
# eu.*.critical -> All EU critical messages
channel.exchange_declare(exchange='events.topic', exchange_type='topic')
# Bind patterns
channel.queue_bind(exchange='events.topic', queue='us_critical', routing_key='us.*.critical')
channel.queue_bind(exchange='events.topic', queue='eu_all', routing_key='eu.#')
5. RPC (Request/Reply)
Pattern: Synchronous request/response using correlation ID.
Request:
import uuid
# Create callback queue for replies
result = channel.queue_declare(queue='', exclusive=True)
callback_queue = result.method.queue
correlation_id = str(uuid.uuid4())
channel.basic_publish(
exchange='',
routing_key='rpc_queue',
properties=pika.BasicProperties(
reply_to=callback_queue,
correlation_id=correlation_id,
),
body='Calculate 42'
)
# Wait for reply with matching correlation_id
Response:
def on_request(ch, method, props, body):
response = f"Result: {body}"
ch.basic_publish(
exchange='',
routing_key=props.reply_to,
properties=pika.BasicProperties(correlation_id=props.correlation_id),
body=response
)
ch.basic_ack(delivery_tag=method.delivery_tag)
Publisher-Consumer Patterns
Publisher Confirms
Purpose: Ensure messages are successfully received by broker.
Configuration:
channel.confirm_delivery()
try:
channel.basic_publish(exchange='', routing_key='tasks', body='Task data')
print("Message confirmed by broker")
except pika.exceptions.UnroutableError:
print("Message could not be routed")
Consumer Acknowledgements
Manual ACK (Recommended):
def callback(ch, method, properties, body):
try:
process_message(body)
ch.basic_ack(delivery_tag=method.delivery_tag)
except Exception as e:
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
channel.basic_consume(queue='tasks', on_message_callback=callback, auto_ack=False)
Auto ACK (Not Recommended):
Prefetch Count (QoS)
Purpose: Control how many unacknowledged messages a consumer can have.
Use Case: Fair dispatch in work queues.
Consumer Cancellation
Graceful Shutdown:
def callback(ch, method, properties, body):
if stop_signal:
ch.basic_cancel(consumer_tag)
ch.stop_consuming()
High Availability & Clustering
Clustering
Purpose: Distribute load and provide fault tolerance.
Architecture:
Features: - Metadata replication - Exchanges, queues, bindings replicated - Message distribution - Messages NOT replicated by default (use quorum queues) - Load balancing - Clients connect to any node
Setup:
# On each node, join cluster
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@node1
rabbitmqctl start_app
# Verify cluster status
rabbitmqctl cluster_status
Quorum Queues
Purpose: Replicated queues for high availability.
Features: - Raft consensus - Leader election, log replication - Data replication - Messages replicated to majority of nodes - Automatic failover - New leader elected if current fails
Configuration:
Recommendation: Use quorum queues for critical workloads.
Mirrored Queues (Classic HA)
Note: Deprecated in favor of quorum queues.
Configuration:
Load Balancing
Options:
- HAProxy - Layer 4 load balancer
- Nginx - HTTP/AMQP load balancing
- Kubernetes Service - ClusterIP with multiple replicas
HAProxy Example:
frontend rabbitmq_amqp
bind *:5672
mode tcp
default_backend rabbitmq_nodes
backend rabbitmq_nodes
mode tcp
balance roundrobin
server rabbit1 rabbit1:5672 check
server rabbit2 rabbit2:5672 check
server rabbit3 rabbit3:5672 check
Federation & Shovel
Federation
Purpose: Connect RabbitMQ clusters across WAN/regions.
Use Cases: - Multi-datacenter deployments - Geo-distributed applications - Cloud to on-premise bridging
Setup:
# Enable federation plugin
rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management
# Define upstream
rabbitmqctl set_parameter federation-upstream upstream1 \
'{"uri":"amqp://remote-host","ack-mode":"on-confirm"}'
# Apply policy
rabbitmqctl set_policy federate-exchanges "^federated\." \
'{"federation-upstream-set":"all"}'
Shovel
Purpose: Move messages between queues/exchanges (same or different clusters).
Use Cases: - Migration between clusters - Forwarding to backup cluster - Aggregating from multiple sources
Setup:
# Enable shovel plugin
rabbitmq-plugins enable rabbitmq_shovel
rabbitmq-plugins enable rabbitmq_shovel_management
# Create shovel
rabbitmqctl set_parameter shovel my-shovel \
'{"src-uri":"amqp://source","src-queue":"source_queue",
"dest-uri":"amqp://dest","dest-queue":"dest_queue"}'
Security & Authentication
User Management
# Add user
rabbitmqctl add_user myuser mypassword
# Set tags (administrator, monitoring, management)
rabbitmqctl set_user_tags myuser administrator
# Set permissions (configure, write, read)
rabbitmqctl set_permissions -p / myuser ".*" ".*" ".*"
# List users
rabbitmqctl list_users
Virtual Host Permissions
# Create vhost
rabbitmqctl add_vhost /production
# Set permissions per vhost
rabbitmqctl set_permissions -p /production myuser "^prod-.*" "^prod-.*" "^prod-.*"
TLS/SSL
Configuration (rabbitmq.conf):
listeners.ssl.default = 5671
ssl_options.cacertfile = /path/to/ca_certificate.pem
ssl_options.certfile = /path/to/server_certificate.pem
ssl_options.keyfile = /path/to/server_key.pem
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = true
Client Connection:
import ssl
ssl_context = ssl.create_default_context(cafile="/path/to/ca_cert.pem")
ssl_context.load_cert_chain("/path/to/client_cert.pem", "/path/to/client_key.pem")
parameters = pika.ConnectionParameters(
host='rabbitmq.example.com',
port=5671,
ssl_options=pika.SSLOptions(ssl_context)
)
connection = pika.BlockingConnection(parameters)
LDAP/OAuth2 Authentication
LDAP Plugin:
Configuration:
auth_backends.1 = ldap
auth_ldap.servers.1 = ldap.example.com
auth_ldap.user_dn_pattern = cn=${username},ou=users,dc=example,dc=com
Monitoring & Management
Management UI
Enable Plugin:
Access: http://localhost:15672
Features: - Queue/exchange overview - Message rates, publish/consume stats - Connection/channel monitoring - User/permission management - Policy configuration
CLI Tools
# List queues
rabbitmqctl list_queues name messages consumers
# List exchanges
rabbitmqctl list_exchanges name type
# List bindings
rabbitmqctl list_bindings
# Node status
rabbitmqctl status
# Cluster status
rabbitmqctl cluster_status
# Memory usage
rabbitmqctl status | grep memory
Prometheus Exporter
Enable Plugin:
Scrape Endpoint: http://localhost:15692/metrics
Key Metrics:
- rabbitmq_queue_messages - Messages in queue
- rabbitmq_queue_messages_ready - Ready messages
- rabbitmq_queue_messages_unacknowledged - Unacked messages
- rabbitmq_connections - Active connections
- rabbitmq_consumers - Active consumers
- rabbitmq_channel_messages_published_total - Published messages
Prometheus Config:
Health Checks
Aliveness Test:
Node Health:
Client Libraries
Python (pika)
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
connection.close()
Go (amqp091-go)
import (
amqp "github.com/rabbitmq/amqp091-go"
)
conn, _ := amqp.Dial("amqp://guest:guest@localhost:5672/")
ch, _ := conn.Channel()
q, _ := ch.QueueDeclare("hello", false, false, false, false, nil)
ch.Publish("", q.Name, false, false, amqp.Publishing{
ContentType: "text/plain",
Body: []byte("Hello World"),
})
Java (Spring AMQP)
@Configuration
public class RabbitConfig {
@Bean
public Queue queue() {
return new Queue("hello");
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
return new RabbitTemplate(connectionFactory);
}
}
// Publish
rabbitTemplate.convertAndSend("hello", "Hello World");
Node.js (amqplib)
const amqp = require('amqplib');
const connection = await amqp.connect('amqp://localhost');
const channel = await connection.createChannel();
await channel.assertQueue('hello');
channel.sendToQueue('hello', Buffer.from('Hello World'));
Kubernetes Deployment
Helm Chart (Bitnami)
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install rabbitmq bitnami/rabbitmq \
--set auth.username=admin \
--set auth.password=secretpassword \
--set replicaCount=3 \
--set clustering.enabled=true \
--set persistence.enabled=true \
--set persistence.size=8Gi
StatefulSet Example
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rabbitmq
spec:
serviceName: rabbitmq
replicas: 3
selector:
matchLabels:
app: rabbitmq
template:
metadata:
labels:
app: rabbitmq
spec:
containers:
- name: rabbitmq
image: rabbitmq:3.13-management
ports:
- containerPort: 5672
name: amqp
- containerPort: 15672
name: management
env:
- name: RABBITMQ_ERLANG_COOKIE
value: "secret-cookie"
- name: RABBITMQ_DEFAULT_USER
value: "admin"
- name: RABBITMQ_DEFAULT_PASS
valueFrom:
secretKeyRef:
name: rabbitmq-secret
key: password
volumeMounts:
- name: data
mountPath: /var/lib/rabbitmq
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 8Gi
---
apiVersion: v1
kind: Service
metadata:
name: rabbitmq
spec:
selector:
app: rabbitmq
ports:
- name: amqp
port: 5672
- name: management
port: 15672
clusterIP: None # Headless service for StatefulSet
RabbitMQ Cluster Operator
Install Operator:
kubectl apply -f https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml
RabbitMQ Cluster Custom Resource:
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmq-cluster
spec:
replicas: 3
image: rabbitmq:3.13-management
persistence:
storageClassName: standard
storage: 10Gi
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1
memory: 2Gi
rabbitmq:
additionalConfig: |
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_k8s
cluster_formation.k8s.host = kubernetes.default.svc.cluster.local
cluster_formation.k8s.address_type = hostname
Performance Tuning
Message Throughput
Batching:
# Publish in batches
for i in range(1000):
channel.basic_publish(exchange='', routing_key='queue', body=f'Message {i}')
# Commit batch
channel.tx_commit()
Async Publishing:
import pika
from pika.adapters.asyncio_connection import AsyncioConnection
async def publish():
connection = await AsyncioConnection.create(parameters)
channel = await connection.channel()
for i in range(10000):
await channel.basic_publish(exchange='', routing_key='queue', body=f'Msg {i}')
Consumer Performance
Prefetch Count:
Multiple Consumers:
Queue Performance
Lazy Queues (Disk-backed):
Use Case: Millions of messages, low memory footprint.
Memory Management
Configuration (rabbitmq.conf):
# Memory threshold (40% of total RAM)
vm_memory_high_watermark.relative = 0.4
# Paging threshold (50% of memory limit)
vm_memory_high_watermark_paging_ratio = 0.5
# Disk free space limit (50GB)
disk_free_limit.absolute = 50GB
Best Practices
1. Use Durable Queues & Persistent Messages
Why: Survive broker restarts.
channel.queue_declare(queue='tasks', durable=True)
channel.basic_publish(
exchange='',
routing_key='tasks',
body='Task data',
properties=pika.BasicProperties(delivery_mode=2)
)
2. Enable Publisher Confirms
Why: Ensure messages are received by broker.
3. Use Manual Acknowledgements
Why: Prevent message loss on consumer failures.
4. Set Prefetch Count
Why: Fair dispatch in work queues.
5. Use Dead Letter Exchanges
Why: Handle failed messages gracefully.
channel.queue_declare(
queue='main_queue',
arguments={
'x-dead-letter-exchange': 'dlx',
'x-dead-letter-routing-key': 'failed'
}
)
6. Monitor Queue Lengths
Why: Detect backpressure and consumer failures.
Alert on: - Queue length > threshold (e.g., 10,000 messages) - Message age > threshold (e.g., 5 minutes)
7. Use Quorum Queues for HA
Why: Data replication and automatic failover.
8. Set Message TTL for Temporary Data
Why: Prevent unbounded growth of stale messages.
9. Use Virtual Hosts for Isolation
Why: Separate environments, teams, or applications.
10. Enable TLS in Production
Why: Encrypt data in transit.
listeners.ssl.default = 5671
ssl_options.cacertfile = /path/to/ca.pem
ssl_options.certfile = /path/to/cert.pem
ssl_options.keyfile = /path/to/key.pem
Troubleshooting
Issue 1: Messages Not Being Consumed
Symptoms: - Messages piling up in queue - Consumers connected but not receiving
Debugging:
-
Check consumer status:
-
Verify consumer prefetch:
-
Check for unacknowledged messages:
-
Restart consumers with manual ACK:
Issue 2: High Memory Usage
Symptoms: - RabbitMQ using excessive memory - Broker triggers memory alarm
Solutions:
-
Enable lazy queues:
-
Reduce prefetch count:
-
Purge old messages:
-
Increase memory threshold:
Issue 3: Connection Refused
Symptoms: - Clients cannot connect - "Connection refused" errors
Solutions:
-
Verify RabbitMQ is running:
-
Check port bindings:
-
Check firewall rules:
-
Verify user credentials:
Issue 4: Cluster Partition
Symptoms: - Nodes not communicating - Split-brain scenario
Detection:
Resolution:
# Stop minority partition nodes
rabbitmqctl stop_app
# Reset node
rabbitmqctl reset
# Rejoin cluster
rabbitmqctl join_cluster rabbit@primary_node
rabbitmqctl start_app
Issue 5: Slow Message Processing
Symptoms: - High latency between publish and consume - Messages delayed
Solutions:
-
Check consumer count:
-
Increase prefetch count:
-
Use multiple channels:
-
Profile consumer code:
Company / Platform Specific Examples
Platform Event Processing
Use Case: Process Tekton pipeline events asynchronously.
Architecture:
Configuration:
# Declare topic exchange
channel.exchange_declare(exchange='platform.events', exchange_type='topic')
# Bind queues
channel.queue_bind(exchange='platform.events', queue='notifications', routing_key='pipeline.*.failed')
channel.queue_bind(exchange='platform.events', queue='metrics', routing_key='pipeline.#')
channel.queue_bind(exchange='platform.events', queue='audit', routing_key='#')
# Publish pipeline event
channel.basic_publish(
exchange='platform.events',
routing_key='pipeline.build.failed',
body=json.dumps({
'pipeline': 'my-app-build',
'status': 'failed',
'timestamp': '2026-03-19T10:00:00Z'
}),
properties=pika.BasicProperties(delivery_mode=2)
)
Consumer (Notification Service):
def on_failed_pipeline(ch, method, properties, body):
event = json.loads(body)
send_slack_notification(f"Pipeline {event['pipeline']} failed!")
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=5)
channel.basic_consume(queue='notifications', on_message_callback=on_failed_pipeline)
channel.start_consuming()
References
- RabbitMQ Documentation: https://www.rabbitmq.com/documentation.html
- AMQP 0-9-1 Reference: https://www.rabbitmq.com/amqp-0-9-1-reference.html
- Management HTTP API: https://www.rabbitmq.com/management.html
- Clustering Guide: https://www.rabbitmq.com/clustering.html
- Production Checklist: https://www.rabbitmq.com/production-checklist.html
- Kubernetes Operator: https://www.rabbitmq.com/kubernetes/operator/operator-overview.html
Last Updated: 2026-03-19 Author: Documentation Team (Company Infrastructure Team) License: CC BY-SA 4.0