A minimal set of console apps demonstrating common RabbitMQ messaging patterns using RabbitMQ.Client (v7.x) and RabbitMQ running locally in Docker.
- .NET SDK
10.0 - Docker Desktop (or Docker Engine)
docker run --rm -it -p 5672:5672 -p 15672:15672 rabbitmq:3-management- AMQP:
localhost:5672 - Management UI:
http://localhost:15672(user/pass:guest/guest)
From the repository root:
dotnet build .\RabbitMQAdvancedPatterns.slnxProjects
- Producer:
RabbitMQAdvancedPatterns\WorkQueueProducer - Consumer:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\WorkQueueConsumer - DLQ consumer:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\DeadLetterConsumer
Terminal A:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\WorkQueueConsumer\WorkQueueConsumer.csprojTerminal B:
dotnet run --project .\RabbitMQAdvancedPatterns\WorkQueueProducer\WorkQueueProducer.csproj -- "task one..."
dotnet run --project .\RabbitMQAdvancedPatterns\WorkQueueProducer\WorkQueueProducer.csproj -- "task two."Notes:
- Messages are sent to a durable queue named
task_queue. - The consumer uses manual acknowledgements (
BasicAckAsync). - Dots (
.) simulate work time (1 second per dot).
Start the DLQ consumer:
Terminal C:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\DeadLetterConsumer\DeadLetterConsumer.csprojSend a failing task (contains the word fail):
Terminal B:
dotnet run --project .\RabbitMQAdvancedPatterns\WorkQueueProducer\WorkQueueProducer.csproj -- "fail this task"Expected:
WorkQueueConsumerrejects the message (BasicRejectAsync(requeue: false))- RabbitMQ routes it to
dead_letter_queueviadlx_exchange DeadLetterConsumerprints the dead-lettered message
Projects
- Publisher:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\PubSubPublisher - Subscriber:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\PubSubSubscriber
Terminal A (and/or B):
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\PubSubSubscriber\PubSubSubscriber.csprojTerminal C:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\PubSubPublisher\PubSubPublisher.csproj -- "hello everyone"Expected:
- Publisher sends to fanout exchange
logs_exchange - Every subscriber receives and prints the broadcast
Projects
- Publisher:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\DirectPublisher - Subscriber:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\DirectSubscriber
Terminal A:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\DirectSubscriber\DirectSubscriber.csproj -- warning errorTerminal B:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\DirectPublisher\DirectPublisher.csproj -- info "this will NOT be received"
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\DirectPublisher\DirectPublisher.csproj -- error "this WILL be received"Expected:
- Messages are published to
direct_logs_exchange - Subscriber receives only the routing keys it bound to (e.g.,
warning,error)
Projects
- Publisher:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\TopicPublisher - Subscriber:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\TopicSubscriber
Terminal A:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\TopicSubscriber\TopicSubscriber.csproj -- "kern.*" "*.critical"Terminal B:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\TopicPublisher\TopicPublisher.csproj -- "kern.critical" "kernel panic"
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\TopicPublisher\TopicPublisher.csproj -- "app.info" "startup ok"Expected:
- Messages are published to
topic_logs_exchange - Subscriber receives only messages whose routing keys match its patterns
This retry demo is implemented as separate projects so it does not change the Work Queue / DLQ demo.
Projects
- Producer:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\RetryProducer - Consumer:
RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\RetryConsumer
Broker entities used by this demo
- Task queue:
retry_demo_task_queue - Retry delay queue (TTL):
retry_demo_retry_queue(defaults to 5s delay) - DLX:
retry_demo_dlx_exchange - DLQ:
retry_demo_dead_letter_queue
Terminal A:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\RetryConsumer\RetryConsumer.csprojTerminal B:
dotnet run --project .\RabbitMQAdvancedPatterns\RabbitMQAdvancedPatterns\RetryProducer\RetryProducer.csproj -- "fail please"Expected:
- The consumer schedules retries by republishing to the TTL-based
retry_demo_retry_queue - After the delay, RabbitMQ dead-letters the message back to
retry_demo_task_queue - After
MaxRetriesis exceeded, the consumer rejects it to the demo DLQ (retry_demo_dead_letter_queue)
You can also watch queue depths in the Management UI: http://localhost:15672.