Roadmap › Microservices & System Design with .NET › Module: Communication
Lessons in this course (9)
4. Asynchronous communication — queues, topics and events
Intermediate★ Must knowLesson 4 of 9
| Concept | Meaning |
|---|---|
| Queue (point-to-point) | One message → one consumer (work distribution). Service Bus queue, RabbitMQ queue |
| Topic / pub-sub | One message → every subscriber gets a copy. Service Bus topics, RabbitMQ fanout exchange, Kafka |
| Command vs event | Command = "do this" (one handler). Event = "this happened" (zero or many listeners) |
| At-least-once delivery | A message can arrive twice → consumers must be idempotent |
| Dead-letter queue | Where messages go after repeated failures, for inspection and replay |
| Event streaming | Ordered, replayable log (Kafka, Event Hubs) — for analytics, IoT, event sourcing |
csharp
// MassTransit consumer — idempotent by checking a processed-message table
public class OrderPlacedConsumer(AppDb db) : IConsumer<OrderPlaced>
{
public async Task Consume(ConsumeContext<OrderPlaced> ctx)
{
if (await db.Processed.AnyAsync(p => p.MessageId == ctx.MessageId)) return; // already handled
db.Invoices.Add(new Invoice(ctx.Message.OrderId, ctx.Message.Total));
db.Processed.Add(new ProcessedMessage(ctx.MessageId!.Value));
await db.SaveChangesAsync();
}
}Benefits: temporal decoupling (consumer can be down), load levelling (queue absorbs peaks), easy to add new subscribers.