Event-Driven Systems: .NET’te Distributed Monolith Tuzağı
01.07.2026
Bugün teknoloji dünyasında garip bir yarış var: Kim projesini daha çok parçaya bölerse, o kadar "modern" mimari kurduğunu sanıyor. Şirketler devasa monolith projelerini alıyor, sırf moda olduğu için 10 farklı mikroservise bölüyor.
Günün sonunda karşılaştığımız manzara ise değişmiyor: Birbirine HttpClient ile göbekten bağlı, biri çöktüğünde dominonun taşları gibi diğerlerini de aşağı çeken bir sistem.
Bunun adı mikroservis değil; monolith bir projenin tüm dezavantajlarını alıp, üzerine bir de network/latency problemlerini eklediğiniz "Distributed Monolith" (Dağıtık Monolit) tuzağıdır.
Senkron İletişimin Bedeli
Eğer OrderService (Sipariş Servisi), bir sipariş geldiğinde PaymentService'e HTTP / REST üzerinden senkron bir istek atıyor ve onun dönmesini bekliyorsa, siz sistemleri birbirinden ayırmadınız; sadece araya kablo çektiniz. O kablonun ucundaki servis geciktiğinde veya ağda bir paket kaybolduğunda tüm sistem kilitlenir.
Gerçek bir sistem mimarı, servislerin birbiriyle doğrudan konuşmaması gerektiğini bilir. Servisler birbirlerinin varlığından bile haberdar olmamalıdır. Çözüm; senkron beklemeleri hayatımızdan çıkarıp Event-Driven dünyaya geçmektir.
.NET Ekosisteminde Çözüm: MassTransit ve Asenkron Dünya
.NET dünyasında bu bağımlılık zincirini kırmanın yolu, in-memory işlemlerde MediatR gibi kütüphaneleri, dağıtık sistemlerde ise MassTransit ile RabbitMQ veya Azure Service Bus gibi Message Broker'ları mimariye dahil etmekten geçer.
- Gevşek Bağımlılık (Loosely-Coupled):
OrderServicesipariş alındığında dış dünyaya "Sipariş Oluşturuldu!"(OrderCreatedEvent) diye bağırır ve işini bitirir. Ödeme servisi o an ayakta mı, çökmüş mü umursamaz. Ödeme servisi ayağa kalktığında o eventi kuyruktan alır ve kendi işini yapar. - Hata Toleransı (Resiliency): Kuyruk mekanizması sayesinde, sistemin bir parçası kapalı olsa bile veri kaybolmaz. Sistem "Fault-Tolerant" hale gelir.
- Performans ve Ölçekleme: Ağ üzerindeki senkron beklemeler (I/O blocking) ortadan kalktığı için thread'leriniz gereksiz yere kilitlenmez.
.NET BackgroundServicesarka planda bu eventleri tüketirken, işlemci çekirdeklerini maksimum verimle kullanabilirsiniz.
Mimari Bir Tercihtir
Her projenin mikroservise ihtiyacı yoktur. Hatta iddia ediyorum; çoğu proje için iyi kurgulanmış, iç mimarisi asenkron eventlerle beslenmiş modüler bir monolit, kötü tasarlanmış 20 mikroservisten çok daha performanslı ve sürdürülebilirdir.
Mühendislik, projeyi kaç parçaya böldüğünüzle değil, o parçaların birbirine ne kadar az muhtaç olduğuyla ölçülür.
Siz mimarinizi esnek ve asenkron mu kurguluyorsunuz, yoksa HTTP isteklerinin arkasında kuyrukta bekleyen servis zincirleri mi yaratıyorsunuz?