sametcancelik.dev
Geri Dön

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.

  1. Gevşek Bağımlılık (Loosely-Coupled): OrderService sipariş 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.
  2. Hata Toleransı (Resiliency): Kuyruk mekanizması sayesinde, sistemin bir parçası kapalı olsa bile veri kaybolmaz. Sistem "Fault-Tolerant" hale gelir.
  3. Performans ve Ölçekleme: Ağ üzerindeki senkron beklemeler (I/O blocking) ortadan kalktığı için thread'leriniz gereksiz yere kilitlenmez. .NET BackgroundServices arka 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?