Bird
Raised Fist0
RabbitMQdevops~7 mins

Event sourcing with RabbitMQ - Commands & Configuration

Choose your learning style10 modes available
Introduction
Event sourcing is a way to record every change in your system as a sequence of events. RabbitMQ helps by sending and storing these events as messages, so you can track what happened and rebuild system state anytime.
When you want to keep a full history of changes to your data for auditing or debugging.
When you need to replay past events to restore system state after a failure.
When multiple parts of your system need to react to the same events independently.
When you want to decouple services so they communicate by sending events instead of direct calls.
When you want to scale event processing by distributing messages across multiple consumers.
Config File - event_sourcing_setup.sh
event_sourcing_setup.sh
#!/bin/bash

# Create a durable exchange for event sourcing
rabbitmqadmin declare exchange name=event_exchange type=fanout durable=true

# Create a durable queue to store events
rabbitmqadmin declare queue name=event_store durable=true

# Bind the queue to the exchange to receive all events
rabbitmqadmin declare binding source=event_exchange destination=event_store

This script sets up RabbitMQ for event sourcing:

  • exchange: A durable fanout exchange named event_exchange that broadcasts events to all bound queues.
  • queue: A durable queue named event_store that stores all events reliably.
  • binding: Connects the exchange to the queue so all events sent to the exchange go into the queue.
Commands
Create a durable fanout exchange named 'event_exchange' to broadcast events to all queues bound to it.
Terminal
rabbitmqadmin declare exchange name=event_exchange type=fanout durable=true
Expected OutputExpected
{"name":"event_exchange","type":"fanout","durable":true,"auto_delete":false,"internal":false,"arguments":{}}
→
name=event_exchange - Sets the exchange name
→
type=fanout - Broadcasts messages to all bound queues
→
durable=true - Keeps exchange after RabbitMQ restarts
Create a durable queue named 'event_store' to store all event messages reliably.
Terminal
rabbitmqadmin declare queue name=event_store durable=true
Expected OutputExpected
{"name":"event_store","durable":true,"auto_delete":false,"arguments":{}}
→
name=event_store - Sets the queue name
→
durable=true - Keeps queue after RabbitMQ restarts
Bind the 'event_store' queue to the 'event_exchange' so it receives all events sent to the exchange.
Terminal
rabbitmqadmin declare binding source=event_exchange destination=event_store
Expected OutputExpected
{"source":"event_exchange","destination":"event_store","destination_type":"queue","routing_key":""}
→
source=event_exchange - The exchange sending messages
→
destination=event_store - The queue receiving messages
Send an event message about a new user creation to the 'event_exchange'. This message will be stored in the 'event_store' queue.
Terminal
rabbitmqadmin publish exchange=event_exchange routing_key= payload='{"event":"user_created","data":{"id":1,"name":"Alice"}}'
Expected OutputExpected
{"routed":true}
→
exchange=event_exchange - Send message to this exchange
→
routing_key= - Empty for fanout exchange
→
payload= - The event data in JSON format
Retrieve one event message from the 'event_store' queue to verify it was stored correctly.
Terminal
rabbitmqadmin get queue=event_store requeue=false count=1
Expected OutputExpected
{ "payload": "{\"event\":\"user_created\",\"data\":{\"id\":1,\"name\":\"Alice\"}}", "payload_bytes": 56, "redelivered": false, "exchange": "event_exchange", "routing_key": "", "message_count": 0 }
→
queue=event_store - The queue to get messages from
→
requeue=false - Remove message from queue after getting
→
count=1 - Get one message
Key Concept

If you remember nothing else from this pattern, remember: RabbitMQ stores every event as a message so you can replay or audit system changes anytime.

Common Mistakes
Creating a non-durable exchange or queue
Events will be lost if RabbitMQ restarts, breaking event sourcing reliability.
Always set durable=true for exchanges and queues to keep events safe across restarts.
Using a direct exchange instead of fanout for event broadcasting
Events will only go to queues matching the routing key, missing other consumers.
Use a fanout exchange to broadcast events to all interested queues.
Not binding the queue to the exchange
Events sent to the exchange won't reach the queue, so no events are stored.
Always bind your event store queue to the event exchange.
Summary
Create a durable fanout exchange to broadcast all events.
Create a durable queue to store all event messages reliably.
Bind the queue to the exchange so it receives every event.
Publish event messages to the exchange to record system changes.
Retrieve messages from the queue to replay or audit events.

Practice

(1/5)
1. What is the main purpose of event sourcing in RabbitMQ?
easy
A. To record all changes as a sequence of events
B. To delete old messages automatically
C. To speed up message delivery by skipping queues
D. To encrypt messages before sending

Solution

  1. Step 1: Understand event sourcing concept

    Event sourcing means storing every change as an event, not just the current state.
  2. Step 2: Connect event sourcing to RabbitMQ

    RabbitMQ can store and forward these events reliably using exchanges and queues.
  3. Final Answer:

    To record all changes as a sequence of events -> Option A
  4. Quick Check:

    Event sourcing = record all changes as events [OK]
Hint: Event sourcing means saving every change as an event [OK]
Common Mistakes:
  • Thinking event sourcing deletes old data
  • Confusing event sourcing with encryption
  • Assuming event sourcing skips queues
2. Which RabbitMQ component is responsible for routing events to queues based on routing keys?
easy
A. Queue
B. Binding
C. Channel
D. Exchange

Solution

  1. Step 1: Identify RabbitMQ components

    Exchanges receive messages and decide where to send them using routing keys.
  2. Step 2: Role of routing keys and bindings

    Bindings connect exchanges to queues, but routing decisions happen inside exchanges.
  3. Final Answer:

    Exchange -> Option D
  4. Quick Check:

    Routing keys route messages via exchanges [OK]
Hint: Exchanges route messages using routing keys [OK]
Common Mistakes:
  • Confusing bindings as routing decision makers
  • Thinking queues route messages
  • Mixing channels with routing
3. Given this RabbitMQ setup:
channel.exchange_declare(exchange='events', exchange_type='direct')
channel.queue_declare(queue='order_events')
channel.queue_bind(queue='order_events', exchange='events', routing_key='order.created')
channel.basic_publish(exchange='events', routing_key='order.created', body='Order123')

What happens when the message is published?
medium
A. Message causes an error due to missing routing key
B. Message is discarded because no queue matches
C. Message is sent to 'order_events' queue
D. Message is sent to all queues bound to 'events' exchange

Solution

  1. Step 1: Analyze exchange and queue binding

    The 'events' exchange is direct type, routing key 'order.created' binds to 'order_events' queue.
  2. Step 2: Check message publish routing

    Message with routing key 'order.created' matches binding, so it goes to 'order_events' queue.
  3. Final Answer:

    Message is sent to 'order_events' queue -> Option C
  4. Quick Check:

    Direct exchange routes by exact routing key [OK]
Hint: Direct exchange sends message only to matching routing key queue [OK]
Common Mistakes:
  • Assuming message goes to all queues
  • Thinking message is discarded without error
  • Forgetting routing key is required
4. You wrote this code to bind a queue but it doesn't receive messages:
channel.queue_bind(queue='events_queue', exchange='events_exchange', routing_key='user.updated')

What is the most likely reason messages are not received?
medium
A. The queue was not declared before binding
B. The routing key used in publishing does not match 'user.updated'
C. The exchange type does not support routing keys
D. The channel was closed before binding

Solution

  1. Step 1: Verify routing key matching

    Messages only reach queues if routing keys match bindings exactly.
  2. Step 2: Check publishing routing key

    If published messages use a different routing key, queue won't get them despite binding.
  3. Final Answer:

    The routing key used in publishing does not match 'user.updated' -> Option B
  4. Quick Check:

    Routing keys must match for delivery [OK]
Hint: Routing keys must match exactly to deliver messages [OK]
Common Mistakes:
  • Assuming exchange type blocks routing keys
  • Forgetting to declare queue before binding
  • Not checking if channel is open
5. You want to implement event sourcing with RabbitMQ to track user actions. Which setup best ensures all user events are stored and can be replayed later?
hard
A. Use a topic exchange with queues bound by event patterns, and enable message persistence and acknowledgments
B. Use a fanout exchange to broadcast events to multiple queues, each storing events for different services
C. Use a direct exchange with one queue per event type, but do not persist messages after consumption
D. Use a headers exchange without bindings, relying on message headers only

Solution

  1. Step 1: Understand event sourcing needs

    Event sourcing requires storing all events reliably and replaying them later.
  2. Step 2: Evaluate exchange types and persistence

    Topic exchange allows flexible routing by event patterns; persistence and acknowledgments ensure events are saved and not lost.
  3. Step 3: Compare options

    Fanout broadcasts but may not filter; direct without persistence loses events; headers without bindings is unreliable.
  4. Final Answer:

    Use a topic exchange with queues bound by event patterns, and enable message persistence and acknowledgments -> Option A
  5. Quick Check:

    Topic exchange + persistence = reliable event sourcing [OK]
Hint: Use topic exchange with persistence for flexible, reliable event storage [OK]
Common Mistakes:
  • Ignoring message persistence
  • Using fanout without filtering
  • Relying on headers exchange without bindings
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard