Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Microservice İletişim Stilleri: Sync Request/Response, Async Event ve Temporal Coupling
Çağıran cevabı beklemek zorundaysa iletişim, kod ne kadar await'li olursa olsun senkrondur ve iki service'i temporal coupling ile birbirine bağlar; cevap şimdi gerekmiyorsa event ya da local kopya tercih edilir. REST, gRPC (deadline'ın server'a taşınması dahil) ve message karşılaştırması, Inventory deploy edilirken checkout simülasyonu, command ile event farkı ve bir karar tablosu.
Message Contract'ları ve Schema Evolution: CloudEvents, AsyncAPI ve Versioning
Message contract'ı bağımsız deploy edilen producer ve consumer'lar arasında bir public API'dir; alan eklemek güvenli, alanı yeniden adlandırmak ya da enum'a değer eklemek ise consumer'ı sessizce ya da gürültüyle kırar, bu yüzden değişiklikler expand-contract ve versiyonlu type adlarıyla yapılır. System.Text.Json ile gerçek kırılma çıktıları, CloudEvents 1.0 envelope'u C# SDK'sıyla, AsyncAPI 3.1 ile doğrulanmış bir event kataloğu ve schema registry uyumluluk modları.
Saga'yı .NET'te Uygulamak: Persist Edilen State Machine, Timeout ve Compensation
Bir saga'yı .NET'te güvenilir kılmak için state'ini correlation id ile bulunan ve concurrency token taşıyan bir tabloda saklar, kararı (adım, message) çiftini eşleyen saf bir switch expression'a bırakır, command'ları aynı transaction'da outbox'a yazar ve her bekleme adımına o adıma bağlı bir timeout koyarsın. EF Core ve SQLite ile kayıp ödeme cevabı, timeout yarışı, geç gelen ödeme ve başarısız refund senaryoları gerçek çıktılarla; aynı saga MassTransit 8 ve Wolverine ile, lisans notlarıyla.
Transactional Outbox ve Inbox: Dual Write Problemini Anlamak ve Doğru Tasarlamak
Veritabanına commit edip ayrıca broker'a publish etmek iki ayrı hata penceresi açar; çözüm, message'ı iş verisiyle aynı transaction'da bir outbox tablosuna yazıp ayrı bir relay ile yayınlamak ve relay'in ürettiği duplicate'leri consumer tarafında inbox ile elemektir. Dual write senaryoları, polling ve CDC relay karşılaştırması, PostgreSQL'de watermark ile message kaybı ve SKIP LOCKED ile çoklu relay gerçek çıktılarla.
Idempotent Consumer: Aynı Message İki Kez Gelirse Ne Olur?
Aynı message'ın ikinci kez işlenmesini önlemenin güvenilir yolu, stabil bir dedup key'i (MessageId ya da iş anahtarı) iş verisiyle aynı transaction'da, consumer başına unique bir inbox tablosuna yazmak ve eşzamanlı duplicate'lerde kararı unique constraint'e bırakmaktır. Check-then-process failure window'u, commit öncesi çökme, iki eşzamanlı kopya ve transaction'a katılamayan e-posta için iki aşamalı kayıt EF Core 10 ve SQL Server 2025 üzerinde gerçek çıktılarla.
Message Ordering ve Partitioning: Sıra Garantisi Nerede Başlar, Nerede Biter?
Broker'lar global sıra vermez; Kafka'da partition key, Azure Service Bus'ta session, RabbitMQ'da single active consumer ile yalnızca anahtar başına sıra elde edilir ve consumer yine de version kontrolüyle sıradan bağımsız olmalıdır. OrderId ile partitioning, BookId key'inin yarattığı hot partition, partition sayısını artırınca taşınan key'ler ve librdkafka ile Java partitioner farkı Kafka 4.2 üzerinde gerçek çıktılarla.
Delivery Guarantee'leri: At-Most-Once, At-Least-Once ve "Exactly-Once" Gerçeği
Delivery guarantee'yi ack ile işin sırası belirler: önce ack at-most-once, önce iş at-least-once demektir; exactly-once yalnızca broker'ın kendi kontrol ettiği işlemlerde mümkündür, dış yan etkilerde at-least-once ile idempotent consumer birlikte effectively-once sağlar. RabbitMQ 4.4 üzerinde yeniden teslim, publisher confirm, duplicate'lerin üç kaynağı ve poison message'ın dead-letter queue'ya düşüşü gerçek çıktılarla.
Channel'lar: Point-to-Point Queue, Publish/Subscribe Topic ve Competing Consumer'lar
Point-to-point channel'da her message'ı tek bir consumer alır, publish/subscribe'da her abone grubu kendi kopyasını alır; competing consumer'lar ise aynı channel'ı paylaşarak ölçekler. Aynı OrderPlaced'i RabbitMQ'ya ve Kafka'ya yayınlayan iki adapter, exchange/queue/binding ile topic/partition/consumer group karşılaştırması, Kafka 4.2 share group'ları ve queue ile log arasındaki seçim gerçek çıktılarla.
Message Türleri: Command, Event ve Query; Event Notification ve Event-Carried State Transfer
Command emir kipindedir ve tek bir alıcıya gider, event geçmiş zamanda bir olgudur ve alıcılarını tanımaz, query ise cevap bekler; bu ayrım message'ın adını, contract sahibini ve channel'ını belirler. MessageId, correlation ve causation id taşıyan bir envelope, Fowler'ın event notification ve event-carried state transfer ayrımı ve domain event ile integration event farkı gerçek çıktılarla.
Neden Messaging? Senkron Çağrı Zincirinden Asenkron İletişime
Senkron HTTP zinciri her bağımlılığın aynı anda ayakta olmasını şart koşar; işi bir queue'ya bırakmak bu temporal coupling'i kırar ve checkout'u e-posta sağlayıcısının çöküşünden korur. Availability çarpımı, Channel<T> ile process içi queue, broker'ın buffer ve load leveling rolü, Web-Queue-Worker ve asenkronluğun bedeli gerçek çıktılarla.