Software · Oct 10, 2026 · 4 dk okuma
Kurumsal .NET'te Performans, Güvenlik ve Ölçeklenebilirlik: Baştan Sona Mimari Vaka
Kurumsal .NET sistemlerinde üç ayrı hedefi ayrı ayrı optimize etmek yerine, istek yolunu ve sınırlarını birlikte tasarlamak daha kalıcı sonuç verir.

Kurumsal bir .NET sistemini ölçeklenebilir yapan şey daha fazla sunucu değil, pahalı işi istek yolundan çıkaran ve güven sınırlarını açık tutan mimaridir. Performans sorunu diye başlayan çalışmaların önemli kısmı bu yüzden cache, thread veya instance ayarından önce veri erişimi ile iş yürütme biçiminde çözülür.
Pratikte kritik karar şudur: hangi iş HTTP isteği içinde tamamlanmalı, hangisi kuyruk üzerinden yürümeli ve hangi veri tutarlılık sınırı içinde değişmelidir? Bu ayrım doğru yapıldığında performans, güvenlik ve yatay ölçekleme birbirini sabote eden üç ayrı proje olmaktan çıkar.
Darboğaz çoğu zaman çalışma sınırıdır
Tipik ASP.NET Core uygulamasında controller veya endpoint ince olsa bile arkasındaki çağrı zinciri pahalı olabilir. Bir sipariş isteği veritabanına birkaç kez gider, yetki kontrolü yapar, belge üretir ve başka bir servise senkron çağrı gönderirse tek bir HTTP isteği çok sayıda kaynağın aynı anda kullanılabilir olmasına bağımlı hale gelir.
Bu noktada yaygın tepki instance sayısını artırmak veya cache eklemektir. Oysa darboğaz connection pool, uzun transaction ya da yavaş bir dış servis ise daha fazla uygulama instance'ı veritabanına daha fazla eşzamanlı bağlantı taşıyarak sorunu büyütebilir. Cache ise kullanıcıya veya tenant'a bağlı yetki sonucunun yanlış anahtarla saklanması halinde performans iyileştirmesini güvenlik açığına dönüştürebilir.
Sınırı önce kodda belirginleştirmek gerekir. ASP.NET Core giriş noktası kimliği doğrular; authorization policy, işlemi yapma hakkını kontrol eder; uygulama servisi kullanım senaryosunu yürütür; EF Core transaction'ı yalnızca birlikte atomik değişmesi gereken kayıtları kapsar. PDF üretimi, e-posta ve uzun süren entegrasyon çağrıları aynı transaction'ın doğal parçası değildir.
Bir sipariş onayı üzerinden istek yolunu ayırmak
Somut bir vaka düşünelim: OrderController, OrderService, AppDbContext ve bir ERP istemcisi bulunan ASP.NET Core servisi. POST /orders/{id}/approve çağrısında finans uzmanının siparişi onaylaması, durum değişikliğinin kaydedilmesi ve ERP aktarımının başlatılması gerekiyor. İlk tasarımda OrderService, EF Core transaction'ını açıyor, siparişi güncelliyor, ERP'yi çağırıyor ve işlem başarılıysa transaction'ı commit ediyor.
Bu düzen veri tutarlılığı açısından güvenli görünebilir, fakat ağ çağrısının süresini veritabanı transaction'ına ekler. ERP yavaşladığında bağlantılar daha uzun tutulur; timeout sonrası istemci isteği tekrarladığında aynı işin iki kez yapılması riski doğar. Uygulama instance'larını çoğaltmak bu bağımlılığı ortadan kaldırmaz.
Daha iyi sınır, yerel değişiklik ile dış dünyaya verilecek sözü aynı veritabanı transaction'ında kaydetmektir. Order satırı Approved durumuna geçerken bir outbox kaydı eklenir ve commit yapılır. Ayrı bir worker outbox kaydını okuyup ERP aktarımını gerçekleştirir; handler idempotent tasarlanır ve aynı mesaj yeniden geldiğinde ikinci bir iş etkisi üretmez.
| Seçim | İstek gecikmesi | Hata sınırı | Ölçekleme davranışı |
|---|---|---|---|
| ERP'yi senkron çağırmak | ERP süresine bağlı | HTTP, DB ve ERP bağlı | Yoğunluk DB ve ERP'ye doğrudan taşınır |
| Outbox + worker | Yerel commit ile sınırlı | ERP hatası istekten ayrılır | API ve worker ayrı ölçeklenebilir |
| Sadece bellek içi background task | Kısa | Process kapanınca iş kaybolabilir | Kalıcılık garantisi zayıf |
Bu değişiklik güvenliği de etkiler. Worker'ın ERP için ayrı bir servis kimliği kullanması, son kullanıcı token'ını arka plan işine taşımaktan daha net bir güven sınırı oluşturur; gereken izin yalnızca aktarım operasyonuyla sınırlandırılabilir. API tarafında tenant veya kaynak sahipliği kontrolü authorization policy içinde yapılmalı, orderId bilen herhangi bir kimliğin kaydı değiştirebildiği varsayılmamalıdır.
Ölçüm kodun sınırlarını izlemeli
Performans incelemesinde ilk bakılacak şey yalnızca ortalama endpoint süresi değildir. İstek süresinin yüksek yüzdelikleri, aktif veritabanı bağlantıları, sorgu süreleri, kuyruk derinliği ve worker işlem süresi aynı istek kimliği veya trace bağlamıyla ilişkilendirilebilmelidir. OpenTelemetry desteği ve ASP.NET Core'un yerleşik gözlemlenebilirlik noktaları bu sınırları görünür kılmak için uygun temel sağlar.
AppDbContext tarafında N+1 sorgularını, gereksiz entity materialization'ını ve büyük sonuç kümelerini incelemek gerekir. Salt okunur sorgularda tracking gerekmiyorsa kapatmak, yalnız gereken kolonları projection ile almak ve sorgu planına uygun indeks oluşturmak genellikle rastgele cache eklemekten daha kontrollü bir yoldur. Cache kullanılacaksa anahtarın tenant ve authorization bağlamıyla ilişkisi açıkça tanımlanmalı, hassas verinin ortak cache'e sızamayacağı gösterilmelidir.
Yatay ölçekleme için API instance'larının mümkün olduğunca yerel session durumuna bağımlı olmaması gerekir. Oran sınırlama, queue kapasitesi ve veritabanı connection pool sınırları da bilinçli seçilmelidir; aksi halde autoscaling sadece aşağı akıştaki sistemi daha hızlı doyurur. Ölçekleme politikası CPU kadar kuyruk birikimi ve dış bağımlılıkların taşıyabileceği eşzamanlılıkla da ilişkilidir.
Pazartesi kararı: senkron yolu küçültün
Mevcut kurumsal .NET servisinde ilk mimari değişiklik olarak yeni bir cache katmanı veya daha büyük instance seçmeyin. En yoğun iş akışlarından birini seçin, HTTP isteği boyunca açık kalan transaction'ı ve dış çağrıları çıkarın; kullanıcıya verilecek kesin cevabın gerektirmediği kalıcı işleri outbox ve idempotent worker sınırına taşıyın.
Ardından authorization kontrolünü kaynak seviyesinde doğrulayın ve API ile worker'ın kimliklerini ayırın. Bu sınır kurulduktan sonra ölçümler size indeks, sorgu, cache veya ek kapasite gerekip gerekmediğini söyler; böylece performans ayarı mimari bir kusuru gizleyen ilk müdahale olmaktan çıkar.
yorumlar
1çok akıcı ve bilgilendirici bir yazı olmuş
Yorum yazmak için giriş yap.
Gmail ile saniyeler içinde, ya da e-posta ile kaydol.