Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Getting Started with Message Queues in .NET: RabbitMQ, Azure Service Bus and Kafka Clients, Which One When
RabbitMQ for flexible routing and per-message ack/retry, Azure Service Bus for a managed service on Azure, Kafka for high volume and replay; the series starts with raw clients and moves on to abstractions. The three brokers' models, a practical comparison table, a program sending and reading the same OrderPlaced with three clients, the Docker Compose environment and a note on Amazon SQS/SNS.
Kafka in .NET with Confluent.Kafka: Producers, Consumer Groups, Offset Commits and Rebalancing
Keep the producer a singleton, use the key for ordering, Acks=All and idempotence, and Flush before dispose; in the consumer set EnableAutoOffsetStore=false, call StoreOffset after processing and write poison messages to a dead-letter topic. Real output: default auto commit skipping a half-processed message, duplicates after kill -9, eager rebalance, KIP-848 and consumer lag.
Message Contracts: Serialization, Versioning and Backward Compatibility
Keep contracts as records separate from domain entities, evolve them only by adding optional fields, turn on RespectRequiredConstructorParameters and RespectNullableAnnotations in System.Text.Json, and carry the version in a type header. Real output: with default settings a rename becomes a 0 TL invoice, a new enum value breaks old consumers, and Schema Registry rejects an incompatible schema with 409.
Observability in Messaging: OpenTelemetry Trace Context, Queue Depth and Consumer Lag
Listen to RabbitMQ.Client 7's built-in ActivitySource and write the traceparent into Kafka headers yourself with a propagator; an order's journey through the API, RabbitMQ, Billing, Kafka and Notification then shows up as five spans in one trace. MessageId and CorrelationId in the log scope, the messaging.process.duration histogram, cardinality, queue depth and Kafka consumer lag, with real output.