RabbitMQ
Persistent Messaging
Topic Exchange
Message Queue
Distributed Systems

RabbitMQ persistent message with Topic exchange

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

RabbitMQ is a popular open-source message-broker software that acts as an intermediary for messaging by accepting and forwarding messages. It enables complex routing scenarios to be implemented with ease. One of the features RabbitMQ offers is the ability to persist messages and use different types of exchanges for routing messages. Topic exchanges are a powerful type of exchange offered by RabbitMQ that route messages based on multiple criteria and complex routing keys. In this article, we will delve deeper into what persistent messages and topic exchanges are, how they function within RabbitMQ, and why they might be useful.

Understanding Topic Exchanges

A topic exchange in RabbitMQ is highly versatile, routing messages based on multiple criteria expressed through routing keys. These keys are essentially patterns that the exchange tries to match with the message's routing key. They can contain words separated by dots (e.g., "user.new" or "user.*"), where each word can be a specific case or a wildcard.

Here’s how the routing within a topic exchange works:

  • * (asterisk) can substitute for exactly one word.
  • # (hash) can substitute for zero or more words.

This flexibility allows a message to be routed to multiple queues based on these matching patterns.

Persistent Messages in RabbitMQ

Persistence in messaging ensures that messages are not lost even in the event of a broker restart. In RabbitMQ, messages can be set to be persistent if they must survive a broker restart, which means they are written to disk. However, the onus is on the publisher to mark messages as persistent.

Example: Sending a Persistent Message with Topic Exchange

Here’s an example in Python, using the pika library, to demonstrate how to send a persistent message with a topic exchange:

python
1import pika
2
3# Connect to a broker
4connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
5channel = connection.channel()
6
7# Declare a topic exchange
8channel.exchange_declare(exchange='logs_topic', exchange_type='topic')
9
10# Send a persistent message
11message = "Hello, this is a persistent message!"
12channel.basic_publish(exchange='logs_topic',
13                      routing_key='app.info',  # Routing key
14                      body=message,
15                      properties=pika.BasicProperties(
16                          delivery_mode=2,  # Make message persistent
17                      ))
18
19print(" [x] Sent %r:%r" % ('app.info', message))
20connection.close()

Receiving Messages with Topic Exchange

Subscribing to a queue that uses a topic exchange involves binding the queue with a specific matching pattern. Here’s how it can be done:

python
1import pika
2
3# Connect to a broker
4connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
5channel = connection.channel()
6
7# Declare the queue
8queue_name = 'logs'
9channel.queue_declare(queue=queue_name, durable=True)
10
11# Bind the queue to a topic exchange
12channel.queue_bind(exchange='logs_topic',
13                   queue=queue_name,
14                   routing_key='app.#')  # Receive all logs from `app`
15
16# Setting up a consumer
17def callback(ch, method, properties, body):
18    print(" [x] Received %r" % body)
19
20channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
21print(' [*] Waiting for logs. To exit press CTRL+C')
22channel.start_consuming()

Key Considerations

Here's a table summarizing the important aspects of using persistent messages with topic exchanges in RabbitMQ:

FeatureDescription
Message DurabilityEnsures messages are written to disk, surviving broker restarts by setting delivery_mode = 2.
Topic ExchangeRoutes messages based on multiple criteria with patterns using wildcards like * and #.
Routing KeysUtilizes dot-separated strings that can contain wildcards to effectively route different messages.
Practical UseIdeal for systems that need strong delivery guarantees and flexible routing strategies.

Conclusion

Persistent messages with topic exchanges in RabbitMQ provide a robust framework for building distributed systems that require reliable message delivery and complex routing capabilities. By understanding and implementing this pattern, developers can ensure that their applications can handle various scenarios gracefully, including service crashes and restarts. The combination of persistence and flexible routing offers a powerful tool for building resilient, decoupled systems.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.