2026-04-14 22:06:55 +00:00
2026-04-14 21:09:30 +00:00
2026-04-14 21:09:30 +00:00
2026-04-14 21:09:30 +00:00
2026-04-14 21:09:30 +00:00
2026-04-14 21:09:39 +00:00
2026-04-14 21:54:01 +00:00
2026-04-14 21:54:58 +00:00
2026-04-14 21:09:30 +00:00
2026-04-14 22:06:55 +00:00
2026-04-14 21:09:30 +00:00

RabbitMQ Hands-On Lab: Build One End-to-End System

This lab gives you one working async system on your laptop.

What You Will Build

A mini order processing pipeline:

  1. producer sends order.created messages.
  2. worker consumes orders and processes them.
  3. worker publishes final status (order.processed or order.failed).
  4. notifier consumes status messages and prints final result.
  5. Failed messages go to a DLQ after retries.

By the end, you will have a real event flow running through RabbitMQ.

Definition of Done

  • You can run all services.
  • You can submit 5 orders and see processed/failure outcomes.
  • You can kill the worker and observe redelivery.
  • You can force failures and see DLQ behavior.

Lab Stack

  • Language: Python
  • Tooling: uv
  • Broker: RabbitMQ 4+ (Docker)
  • Library: pika

Step 1: Project Setup (10 min)

  • Create files:

  • docker-compose.yml

  • pyproject.toml (created by uv init)

  • producer.py

  • worker.py

  • notifier.py

  • Initialize project and dependency with uv:

uv init --name rabbitmq-lab
uv add pika==1.3.2
  • Put this in docker-compose.yml:
version: "3.9"
services:
  rabbitmq:
    image: rabbitmq:4-management
    ports:
      - "5672:5672"
      - "15672:15672"
  • Start RabbitMQ:
docker compose up -d
  • Open UI: http://localhost:15672 (guest / guest).

Step 2: RabbitMQ Topology (15 min)

Create these resources from code (preferred) or UI:

  • Exchange orders.x (direct)
  • Exchange orders.dlx (direct)
  • Queue orders.q
  • Queue orders.processed.q
  • Queue orders.failed.q
  • Queue orders.dlq

Bindings:

  • orders.q <- orders.x with order.created
  • orders.processed.q <- orders.x with order.processed
  • orders.failed.q <- orders.x with order.failed
  • orders.dlq <- orders.dlx with order.dead

Queue args for orders.q:

  • x-dead-letter-exchange=orders.dlx
  • x-dead-letter-routing-key=order.dead

Step 3: Producer (20 min)

  • producer.py should publish 5 JSON orders to routing key order.created.
  • Each message should include:
  • order_id
  • user_id
  • amount
  • should_fail (set true for at least 1 order)
  • retry_count (start at 0)
  • Mark messages persistent.

Success check:

  • Running uv run producer.py prints “Published order …” 5 times.

Step 4: Worker (35 min)

  • worker.py consumes from orders.q with manual ACK.
  • For each message:
  • Parse JSON
  • Simulate processing (sleep(1))
  • If should_fail and retry_count < 2, republish same order with retry_count + 1 to order.created, ACK original.
  • If should_fail and retry_count >= 2, publish to order.failed, ACK original.
  • Else publish to order.processed, ACK original.

Important:

  • Set prefetch_count=1.
  • Use persistent publish for all outgoing messages.

Success check:

  • You see logs for retries and final outcomes.

Step 5: Notifier (15 min)

  • notifier.py consumes both orders.processed.q and orders.failed.q.
  • Print concise final messages, e.g.:
  • ORDER 1001 PROCESSED
  • ORDER 1003 FAILED AFTER RETRIES
  • ACK all notifier messages.

Success check:

  • After running producer, notifier shows both success and failure events.

Step 6: End-to-End Run (10 min)

Run in 3 terminals:

  • Terminal A: uv run worker.py
  • Terminal B: uv run notifier.py
  • Terminal C: uv run producer.py

Expected behavior:

  • Normal orders finish in orders.processed.q path.
  • Failing orders retry 2 times then go orders.failed.q.

Step 7: Failure Drill (10 min)

  • Start worker and producer.
  • Kill worker while processing a message.
  • Restart worker.
  • Verify unacked message is redelivered and processed.

Step 8: DLQ Drill (10 min)

  • In worker, temporarily basic_nack(requeue=False) for one special order.
  • Verify message appears in orders.dlq.
  • Inspect message payload from RabbitMQ UI.

What You Learn (Concrete)

  • RabbitMQ core flow (producer -> exchange -> queue -> consumer)
  • Routing keys and direct exchange
  • Manual ACK and redelivery
  • Retry strategy and failure handling
  • DLQ basics used in real systems