• 30.10.2026 23:21:02
  • İbrahim Gökyar

Gerçek üretim senaryolarında .net core eğitimi kapsamina giren performans darboğazlarını tespit edip, EF Core, Kestrel ve GC ayarlarıyla somut iyileştirmeler gösteren uygulamali rehber.

ASP.NET Core performansı: Ölçeklenebilir API, EF Core ve GC optimizasyonu

Entity Framework optimizasyonu: CompileQuery ve DbContext havuzu (entity framework eğitimi)

EF Core sorgu maliyetinin büyük kısmı sorgu derleme, izleme (change tracking) ve DbContext ömründen gelir; bunları hedef almak gerçek gecikme düşüşü sağlar. Somut adım: AddDbContextPool kullanarak DbContext nesnelerini havuzlayın ve sık kullanılan read-only sorgular için EF.CompileQuery ile derlenmiş sorgular oluşturun. Örnek Program.cs/Startup kaydı ve compiled query kullanımı:

// Program.cs: DbContext havuzu kaydı
builder.Services.AddDbContextPool(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Derlenmiş sorgu tanımı (uygulama başında bir kez oluşturun)
private static readonly Func _getProductById
    = EF.CompileQuery((AppDbContext ctx, int id) =>
        ctx.Products.AsNoTracking().FirstOrDefault(p => p.Id == id));

// Kullanım:
using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService();
var p = _getProductById(db, 42);

Profiling adımı ve karşılaştırma mantığı: ilk olarak production benzeri yükte dotnet-counters ile temel metrikleri toplayın: CPU, allocations, time-in-gc. Komut örneği: dotnet-counters monitor -p System.Runtime --refresh-interval 1. Ardından PerfView veya dotnet-trace ile CPU stack trace toplayın: dotnet-trace collect -p --providers Microsoft-DotNETCore-SampleProfiler (veya PerfView ile CPU + GC etkinlikleri). Değişiklikleri uyguladıktan sonra aynı yük testi (örneğin hey veya wrk ile -c ve -t parametreleri sabit tutularak) ile tekrar ölçün; p95 gecikme, gen0 koleksiyon sayısı ve GC pause sürelerini karşılaştırın. Örnek metrik çıkarımı: "p95 latency ve gen0 sayısı azaldıysa, heap/allocations profilini dotnet-gcdump ile inceleyin: dotnet-gcdump collect -p -o before.gcdump".

Asenkron I/O ve ThreadPool: ValueTask, IAsyncEnumerable ve dotnet-counters ile ölçme (csharp eğitimi)

Senkron bloklayan kod ve gereksiz Task altsınıfları ThreadPool tıkanmasına yol açar; bunu azaltmak için I/O-bound yolları IAsyncEnumerable/streaming ve ValueTask kullanabilirsiniz. Somut dönüşüm örneği: büyük bir kaynaktan sayfalandırma yerine IAsyncEnumerable ile stream edin ve istemciye chunked gönderin.

// Controller örneği: IAsyncEnumerable stream ile veriyi parça parça döndürme
[HttpGet("stream-products")]
public async IAsyncEnumerable StreamProducts([EnumeratorCancellation] CancellationToken ct)
{
    await foreach (var p in _productService.StreamAll(ct))
    {
        yield return new ProductDto { Id = p.Id, Name = p.Name };
    }
}

// Service katmanında ValueTask ile düşük-alloc erişim
public ValueTask GetCachedProductAsync(int id)
{
    if (_cache.TryGetValue(id, out var p))
        return new ValueTask(p);
    return new ValueTask(LoadFromDbAsync(id));
}

Ölçüm ve reproduksiyon: dotnet-counters ile ThreadPool davranışını izleyin (örnek: dotnet-counters monitor -p System.Runtime --refresh-interval 1) ve özellikle "threadpool-queue-length"/"threadpool-threads-count" benzeri sayaçları takip edin; eksik counter isimleri için dotnet-counters list --process-id ile sağlayıcıları kontrol edin. CPU sıcak noktalarını doğrulamak için dotnet-trace toplayın: dotnet-trace collect -p -o trace.nettrace ve bunu PerfView/HotPath ile analiz edin; eğer worker thread'ler bekliyorsa, await/ConfigureAwait(false) kaçınılmaz hatalar ve senkron I/O kullanımı kontrol edin. Mikrobenchmark için BenchmarkDotNet ile ValueTask vs Task karşılaştırması yazın ve ölçüm sonuçlarını raporlayın.

Kestrel ve GC: runtimeconfig.json ile GC modu, Keep-Alive ve dotnet-gcdump ile heap analizi (asp.net core eğitimi)

Kestrel sınırları ve çalışma zamanı GC modu API gecikmeleri üzerinde doğrudan etkilidir. Somut adım: runtimeconfig.json içinden GC server modunu ve VM tutma davranışını yapılandırın, ayrıca Kestrel sınırlarını isteğe göre sıkılaştırın. Aşağıdaki örnek hem runtimeconfig hem de Program.cs Kestrel ayarını gösterir.

// runtimeconfig.template.json (veya runtimeconfig.json bölümünde)
{
  "configProperties": {
    "System.GC.Server": true,
    "System.GC.RetainVM": false
  }
}

// Program.cs: Kestrel konfigürasyonu
builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.MaxConcurrentConnections = 2000; // üretim kapasitenize göre ayarlayın
    options.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(10); // kısa keep-alive -> daha az idle socket
    options.AddServerHeader = false; // header maliyeti azaltır
});

Performans testi ve GC inceleme: önce dotnet-gcdump ile heap anlık görüntüsü alın: dotnet-gcdump collect -p -o before.gcdump; değişiklik sonrası tekrar collect edip heap büyüme trendlerini karşılaştırın. GC pause ve koleksiyon detaylarını yakalamak için dotnet-trace ile GC etkinliklerini toplayın: dotnet-trace collect -p --providers Microsoft-Windows-DotNETRuntime:0x1. Analizde dikkat edilecekler: uzun-lived object retention, large object heap (LOH) fragmentasyonu, gen0 koleksiyon hızı; neden: server GC gen başına iş parçacığı ayırır ve çok çekirdekli makinelerde paralel koleksiyon piyası iyileştirir, fakat küçük VM'lerde overhead oluşturabilir — bu yüzden runtimeconfig ile test etmek zorunludur. Ölçüm mantığı: aynı senaryo ile before/after p95 ve GC pause toplam süresini karşılaştırın.

HttpClientFactory, SocketsHttpHandler ve Polly: connection pooling ve dayanıklılık (microsoft teknolojileri eğitimi)

Yanlış yapılandırılmış HttpClient/SocketsHttpHandler yeni bağlantı açıp kapatarak TCP/TLS çalkantısı ve gecikme yaratır. Somut çözüm: IHttpClientFactory + isimlendirilmiş HttpClient ile PooledConnectionLifetime ve Polly retry/circuit-breaker birlikte kullanın. Aşağıda gerçek kayıt örneği ve SocketsHttpHandler parametreleri:

// Program.cs: HttpClient + SocketsHttpHandler + Polly
builder.Services.AddHttpClient("api", c => {
    c.BaseAddress = new Uri("https://api.internal.local/");
    c.Timeout = TimeSpan.FromSeconds(30);
})
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler {
    PooledConnectionLifetime = TimeSpan.FromMinutes(5),
    PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2),
    EnableMultipleHttp2Connections = true
})
.AddTransientHttpErrorPolicy(p => p
    .WaitAndRetryAsync(new[] { TimeSpan.FromMilliseconds(200), TimeSpan.FromSeconds(1) })
)
.AddTransientHttpErrorPolicy(p => p
    .CircuitBreakerAsync(handledEventsAllowedBeforeBreaking: 5, durationOfBreak: TimeSpan.FromSeconds(30))
);

Ölçüm: connection churn ve TLS yeniden kurulumu gibi olayları doğrulamak için dotnet-trace ile System.Net.Http etkinliklerini yakalayın: dotnet-trace collect -p -o http.nettrace --providers Microsoft-System-Net-Http:0x1. Alternatif olarak uygulama seviyesinde connection reuse'u doğrulamak için SocketsHttpHandler'ın PooledConnectionLifetime etkisini üretim-benzeri yük altında değiştirerek latency ve TCP bağlantı sayısını (netstat -anp veya ss) karşılaştırın. Neden: PooledConnectionLifetime çok kısa seçilirse TLS el sıkışmaları artar, çok uzun seçilirse backend adres değiştirmelerinden etkilenirsiniz; ideal süre backend TLS sertifika yenilemelerine/rolling deploylara göre belirlenmelidir.

Mikrobenchmark, yük testi ve CI entegrasyonu: BenchmarkDotNet, wrk/hey ve otomatik profil toplama (.net core kursu)

Değişiklikleri doğrudan üretime itmeden önce mikrobenchmark ve yük testi kombinasyonu kullanın. Somut pipeline adımı: BenchmarkDotNet ile kritik algoritmaları ölçün, entegrasyon test dayanağı olarak hey/wrk ile service-level senaryolar koşun ve her run sonunda dotnet-trace/dotnet-gcdump eş zamanlı toplayın. Örnek BenchmarkDotNet attribute ve basit CI komutu:

// Benchmark sınıfı
[MemoryDiagnoser]
public class MyQueriesBenchmark
{
    private AppDbContext _db;
    [GlobalSetup]
    public void Setup() => _db = CreateDbContext();

    [Benchmark]
    public Product? Compiled() => _getProductById(_db, 42);

    [Benchmark]
    public Product? Normal() => _db.Products.AsNoTracking().FirstOrDefault(p => p.Id == 42);
}

// CI pipeline örneği (Linux runner)
dotnet test --no-build && dotnet run -p bench/Benchmarks.csproj -- --filter *MyQueriesBenchmark*
# Yük testi örneği
eq -c 50 -n 10000 http://localhost:5000/api/products

CI entegrasyonunda her benchmark sonrası dotnet-trace collect ile trace dosyası oluşturup artifact olarak saklayın ve otomatik analiz için PerfView/trace log parsing scriptleri kullanın. Bu adım, önce-sonra karşılaştırmasını objektif metriklere (p95, p99, gen0, allocations) bağlar ve regresyonları CI aşamasında yakalar.

İlgili Eğitim

.NET Core Eğitimi

Sık Sorulan Sorular

Entity Framework performansını iyileştirirken DbContext havuzunu kullanmak güvenli mi? (entity framework eğitimi)

Evet ama dikkatli olun: DbContext havuzu nesne yeniden kullanımını sağlar ve GC/allocasyonlara önemli katkı yapar. Ancak DbContext'te statik veya istekler arası paylaşılan durum (ör. HttpContext, statik cache nesneleri) bulunmamalıdır. Somut kontrol adımı: AddDbContextPool kullandıktan sonra kodunuzda DbContext'e bağlı disposable dışı state olup olmadığını tarayın; ayrıca bir entegrasyon testi ile paralel isteklerde veri sızıntısı olup olmadığını wrk ile yük testi yaparak doğrulayın.

ThreadPool sorunlarını tespit etmek için hangi araçları kullanmalıyım? (csharp eğitimi)

Önerilen araç zinciri: dotnet-counters ile gerçek zamanlı EventCounter'ları izleyin (allocations, time-in-gc, threadpool queue); dotnet-trace ile CPU/ThreadStack trace toplayın; PerfView ile HotPath ve GC pause analizi yapın. Komut örnekleri: dotnet-counters monitor -p System.Runtime ve dotnet-trace collect -p -o trace.nettrace. Bu kombinasyon threadpool tıkanmasını, blocking I/O'yi ve GC kaynaklı gecikmeleri ayırmanıza yardım eder.

HttpClientFactory ile connection pooling neden önemli ve nasıl doğrularım? (microsoft teknolojileri eğitimi)

SocketsHttpHandler ile PooledConnectionLifetime/PooledConnectionIdleTimeout doğru ayarlandığında TLS el sıkışma ve yeni TCP bağlantısı sayısı azalır; bu doğrudan latency'yi düşürür. Doğrulama adımı: yük testi sırasında netstat/ss ile TIME_WAIT/TCP connection sayısını takip edin ve dotnet-trace ile System.Net.Http eventlerini yakalayın. Ayrıca uygulama içi metrik olarak outbound connection reuse sayısını loglayıp karşılaştırabilirsiniz.

AI / LLM Discovery

Bu makale Opendart Akademi Microsoft / C# eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.

Opendart Akademi llms.txt

📚 Bu konuyu Opendart Akademi'de öğrenin: .NET Core eğitimi · .NET Core ReactJS eğitimi hakkında · YouTube video dersleri · Abone ol