Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
14 posts found
Getting Started with Message Queues in .NET: RabbitMQ, Azure Service Bus and Kafka Clients, Which One When
Backend PART 01

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.

8 Nov 2026 11 min 2
First Producer and Consumer with RabbitMQ.Client 7: Async API, Connection/Channel Lifecycle and Manual Ack
Backend PART 02

First Producer and Consumer with RabbitMQ.Client 7: Async API, Connection/Channel Lifecycle and Manual Ack

Keep one IConnection for the application's lifetime, never share an IChannel across threads, verify publishes with publisher confirmations and mandatory, and run the consumer inside a BackgroundService with autoAck=false and prefetch. Real output shows a prefetch-less consumer pulling 498 messages into memory, autoAck losing 17 messages, automatic recovery and graceful shutdown.

8 Nov 2026 13 min 2
RabbitMQ Topology in Code: Exchange Types, Bindings, Quorum Queues and Streams
Backend PART 03

RabbitMQ Topology in Code: Exchange Types, Bindings, Quorum Queues and Streams

Use quorum queues and topic exchanges for durable business messages, declare the topology idempotently at startup, and leave limits that may change (TTL, max-length, delivery-limit, DLX) to a policy instead of queue arguments. Real output: nine copies from four routing keys, a PRECONDITION_FAILED error, fanout cache invalidation, stream replay and reject-publish.

8 Nov 2026 11 min 2
Azure Service Bus .NET SDK: Queues, Topics/Subscriptions, Sessions and ServiceBusProcessor
Backend PART 04

Azure Service Bus .NET SDK: Queues, Topics/Subscriptions, Sessions and ServiceBusProcessor

Register ServiceBusClient as a singleton with AddAzureClients, use managed identity instead of a connection string in Azure, run ServiceBusProcessor with AutoCompleteMessages=false and lock renewal, and use sessions for ordered work. Real emulator output: lock loss, three attempts hitting the DLQ in one second, filters, sessions, scheduled messages and duplicate detection.

8 Nov 2026 11 min 3
Kafka in .NET with Confluent.Kafka: Producers, Consumer Groups, Offset Commits and Rebalancing
Backend PART 05

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.

8 Nov 2026 12 min 3
Message Contracts: Serialization, Versioning and Backward Compatibility
Backend PART 06

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.

8 Nov 2026 10 min 2
Messaging with MassTransit: Consumers, Publish/Send and Broker Topology — v9 Licensing and Alternatives
Backend PART 07

Messaging with MassTransit: Consumers, Publish/Send and Broker Topology — v9 Licensing and Alternatives

MassTransit takes over connections, acks, serialization and topology, reducing a consumer to a single IConsumer<T>; the price is its own exchange conventions, an envelope format and, in v9, a commercial licence. We move Billing to MassTransit 8.5.12, show publish vs send, the resulting RabbitMQ topology and the envelope, see v9 refuse to start without a licence, and build a decision table across v8, Wolverine, Rebus, NServiceBus and Brighter.

8 Nov 2026 11 min 2
Retry and Redelivery in Consumers: Immediate, Delayed and Exponential Backoff
Backend PART 08

Retry and Redelivery in Consumers: Immediate, Delayed and Exponential Backoff

Handle transient failures with a short in-memory retry and longer waits through the broker; never retry permanent failures, send them to the DLQ. Real output shows nack-requeue looping 8036 times in 5 seconds on RabbitMQ 4.4, TTL + DLX wait queues, the quorum queue's built-in delayed retry, scheduled retry in Service Bus, Kafka retry topics and MassTransit UseMessageRetry.

8 Nov 2026 17 min 3
Managing Dead-Letter Queues: Finding, Inspecting and Reprocessing Poison Messages
Backend PART 09

Managing Dead-Letter Queues: Finding, Inspecting and Reprocessing Poison Messages

Run the DLQ like a work queue: read why each message failed from its headers, alert on growth, and after the fix send it back with a dry run, filters, a cap and your own replay counter. Real output shows RabbitMQ's x-death count not advancing on a client republish, Service Bus DLQ reason codes, a wrong original-topic bug in a Kafka DLT and MassTransit _error headers.

8 Nov 2026 12 min 2
Idempotent Consumers and the Inbox: When the Same Message Arrives Twice
Backend PART 10

Idempotent Consumers and the Inbox: When the Same Message Arrives Twice

Stop a message from being processed twice with a unique constraint in the database, not with a check: write an inbox row keyed by MessageId in the same transaction as the business data, or apply ON CONFLICT to the business key. A real run of check-then-act issuing two invoices, inbox and upsert on PostgreSQL, side effects, dedupe cleanup and the MassTransit inbox.

8 Nov 2026 11 min 4
Transactional Outbox in .NET: EF Core, a BackgroundService Relay and the MassTransit/Wolverine Outbox
Backend PART 11

Transactional Outbox in .NET: EF Core, a BackgroundService Relay and the MassTransit/Wolverine Outbox

Write the message to an outbox table in the same transaction as the business data instead of to the broker, and let a BackgroundService relay pick rows with FOR UPDATE SKIP LOCKED and publish them with confirms. A real run of two instances publishing 200 messages exactly once and returning 201 while the broker is down; why the relay is at-least-once and unordered; MassTransit bus outbox, Wolverine and CDC.

8 Nov 2026 12 min 5
Observability in Messaging: OpenTelemetry Trace Context, Queue Depth and Consumer Lag
Backend PART 12

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.

8 Nov 2026 11 min 4
Blog Map