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
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
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
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
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
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
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.



