Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
.NET'te Message Queue ile Çalışmaya Giriş: RabbitMQ, Azure Service Bus ve Kafka Client'ları, Hangi Durumda Hangisi
Esnek yönlendirme ve mesaj bazında ack/retry için RabbitMQ, Azure'da yönetilen servis için Azure Service Bus, yüksek hacim ve replay için Kafka; seri raw client ile başlayıp abstraction'lara geçiyor. Üç broker'ın modeli, pratik karşılaştırma tablosu, aynı OrderPlaced'ı üç client ile gönderip okuyan program, Docker Compose ortamı ve Amazon SQS/SNS notu.
RabbitMQ.Client 7 ile İlk Producer ve Consumer: Async API, Connection/Channel Yaşam Döngüsü ve Manual Ack
IConnection'ı uygulama ömrü boyunca tek tut, IChannel'ı thread'ler arasında paylaşma, publish'i publisher confirmation ve mandatory ile doğrula, consumer'ı BackgroundService içinde autoAck=false ve prefetch ile çalıştır. Prefetch'siz consumer'ın 498 mesajı belleğe çekmesi, autoAck ile 17 mesajın kaybolması, automatic recovery ve graceful shutdown gerçek çıktılarla.
RabbitMQ Topology'si Kodda: Exchange Tipleri, Binding, Quorum Queue ve Stream
Kalıcı iş mesajları için quorum queue ve topic exchange kullan, topology'yi startup'ta idempotent declare et, değişebilecek limitleri (TTL, max-length, delivery-limit, DLX) queue argümanı yerine policy'ye bırak. Dört routing key'den dokuz kopya, PRECONDITION_FAILED hatası, fanout ile cache invalidation, stream replay ve reject-publish gerçek çıktılarla.
Azure Service Bus .NET SDK: Queue, Topic/Subscription, Session'lar ve ServiceBusProcessor
ServiceBusClient'ı AddAzureClients ile singleton kaydet, Azure'da connection string yerine managed identity kullan, ServiceBusProcessor'ı AutoCompleteMessages=false ve lock renewal ile çalıştır, sıralı iş için session kullan. Emulator'de lock kaybı, exception'da üç denemenin aynı saniyede DLQ'ya düşmesi, filter'lar, session, scheduled message ve duplicate detection gerçek çıktılarla.
Confluent.Kafka ile .NET'te Kafka: Producer, Consumer Group, Offset Commit ve Rebalance
Producer'ı singleton tut, key ile sıra, Acks=All ve idempotence kullan, dispose öncesi Flush et; consumer'da EnableAutoOffsetStore=false ile işlem sonrası StoreOffset yap ve poison mesajı dead-letter topic'e yaz. Varsayılan auto commit'in yarım kalan mesajı atlaması, kill -9 sonrası tekrar, eager rebalance, KIP-848 ve consumer lag gerçek çıktılarla.
Mesaj Contract'ları: Serialization, Versioning ve Geriye Dönük Uyumluluk
Contract'ı domain entity'sinden ayrı record'larla tut, yalnızca opsiyonel alan ekleyerek ilerle, System.Text.Json'da RespectRequiredConstructorParameters ve RespectNullableAnnotations'ı aç, sürümü type header'ında taşı. Varsayılan ayarlarla rename'in 0 TL'lik faturaya dönüşmesi, enum'a eklenen değerin eski consumer'ı kırması ve Schema Registry'nin uyumsuz şemayı 409 ile reddetmesi gerçek çıktılarla.
MassTransit ile Mesajlaşma: Consumer, Publish/Send ve Broker Topology'si — v9 Lisansı ve Alternatifler
MassTransit, connection, ack, serialization ve topology'yi üstlenip consumer'ı tek bir IConsumer<T>'ye indirir; bedeli kendi exchange convention'ı, zarf formatı ve v9'da ticari lisans. Billing'i MassTransit 8.5.12'ye taşıyıp publish/send farkını, oluşan RabbitMQ topology'sini ve zarfı gösteriyor, v9'un lisanssız açılmadığını gerçek çıktıyla görüp v8, Wolverine, Rebus, NServiceBus ve Brighter arasında karar tablosu kuruyoruz.
Consumer'da Retry ve Redelivery: Immediate, Delayed ve Exponential Backoff
Geçici hatayı kısa in-memory retry'la, uzun beklemeyi broker'la çöz; kalıcı hatayı hiç deneme, DLQ'ya gönder. RabbitMQ 4.4'te nack ile requeue'nun 5 saniyede 8036 teslimlik döngüsü, TTL + DLX bekleme queue'ları, quorum queue'nun yerleşik delayed retry'ı, Service Bus'ta scheduled retry, Kafka retry topic'leri ve MassTransit UseMessageRetry gerçek çıktılarla.
Dead-Letter Queue Yönetimi: Poison Message'ı Bulmak, İncelemek ve Yeniden İşlemek
DLQ'yu bir iş listesi gibi yönet: mesajın neden düştüğünü header'lardan oku, büyümesini alarma bağla, düzeltmeden sonra dry-run, filtre, üst sınır ve kendi replay sayacınla geri gönder. RabbitMQ'da x-death'in client'ın geri yayınladığı mesajda ilerlemediği, Service Bus DLQ sebep kodları, Kafka DLT'de yanlış orijinal topic hatası ve MassTransit _error header'ları gerçek çıktılarla.
Idempotent Consumer ve Inbox: Aynı Mesaj İki Kez Geldiğinde
Aynı mesajın ikinci kez işlenmesini kontrolle değil, veritabanındaki bir unique constraint'le engelle: MessageId'li inbox satırını iş verisiyle aynı transaction'da yaz ya da iş anahtarına ON CONFLICT uygula. Check-then-act'in iki fatura kestiği gerçek koşu, PostgreSQL ile inbox ve upsert, yan etkiler, dedupe temizliği ve MassTransit inbox'ı.
.NET'te Transactional Outbox: EF Core, BackgroundService Relay ve MassTransit/Wolverine Outbox
Mesajı broker'a değil, iş verisiyle aynı transaction'da bir outbox tablosuna yaz; bir BackgroundService relay'i satırları FOR UPDATE SKIP LOCKED ile alıp confirm'le yayınlasın. İki instance'ın 200 mesajı tek kez yayınladığı, broker kapalıyken 201 dönüp sonradan gönderdiği gerçek koşu; relay'in at-least-once ve sırasız olması, MassTransit bus outbox, Wolverine ve CDC.
Mesajlaşmada Observability: OpenTelemetry Trace Context, Queue Depth ve Consumer Lag
RabbitMQ.Client 7'nin hazır ActivitySource'unu dinle, Kafka'da traceparent'ı propagator ile header'a kendin yaz; bir siparişin API, RabbitMQ, Billing, Kafka ve Notification yolculuğu tek trace'te beş span olarak görünür. Log scope'unda MessageId ve CorrelationId, messaging.process.duration histogram'ı, kardinalite, queue depth ve Kafka consumer lag ölçümü gerçek çıktılarla.