Bu .net core eğitimi rehberi, ASP.NET Core Output Cache ile güvenli cache anahtarı kurmayı, tag tabanlı geçersizleştirmeyi ve bombardier ile sıcak-soğuk istek farkını ölçmeyi ele alır.
ASP.NET Core Eğitimi: Output Cache ile Doğru HTTP Önbelleği
asp.net core eğitimi: Output Cache için doğru aday endpoint'i seçmek
Output Cache, aynı HTTP temsilinin tekrar üretildiği genel erişimli GET endpoint'lerinde anlamlıdır. Örneğin ürün kataloğu sayfalama endpoint'i EF Core sorgusu, JSON serileştirme ve ağ yazımı yapıyorsa, cache hit durumunda handler ve veritabanı hiç çalışmaz. Buna karşılık kullanıcıya özel sepet, izin sonucu veya tek kullanımlık imzalı URL üreten endpoint'i cache'lemek veri sızıntısı üretir. İlk envanteri üretim erişim loglarından çıkarın: en az 5 dakika boyunca endpoint, durum kodu, query string ve p95 gecikmeyi kaydedin; aday olarak yüksek istek sayısına sahip, 200 dönen ve kullanıcıya göre değişmeyen endpoint'leri seçin.
app.MapGet("/api/tenants/{tenantId}/products", async (
string tenantId,
int page,
int pageSize,
CatalogDbContext db,
CancellationToken ct) =>
{
var items = await db.Products
.AsNoTracking()
.Where(x => x.TenantId == tenantId && x.IsPublished)
.OrderBy(x => x.Name)
.Skip((page - 1) * pageSize)
.Take(Math.Clamp(pageSize, 1, 100))
.Select(x => new ProductListItem(x.Id, x.Name, x.Price))
.ToListAsync(ct);
return Results.Ok(items);
});Bu örnekte AsNoTracking cache'in yerine geçmez. AsNoTracking, EF Core change tracker'a entity eklenmesini engeller; her istekte yine SQL, materialization ve JSON yazımı vardır. entity framework eğitimi sırasında bu ayrımı ölçmek için önce sadece AsNoTracking ile, sonra Output Cache eklenmiş halde aynı yük testini çalıştırın. Cache hit sayısının SQL komutlarını düşürdüğünü doğrulamak için geliştirme ortamında Microsoft.EntityFrameworkCore.Database.Command log kategorisini Information seviyesinde açın.
.net core kursu için cache anahtarı ve varyasyon politikası tasarımı
Cache doğruluğu, TTL'den önce cache anahtarına bağlıdır. Aşağıdaki politika tenant, sayfalama ve sıralamayı anahtara katar. Böylece tenant A'nın ilk sayfası tenant B'ye dönmez. SetVaryByQuery("*") kullanmayın: izleme parametreleri, rastgele filtreler veya saldırganın ürettiği query değerleri sınırsız anahtar kardinalitesi oluşturur. Bunun yerine sözleşmede desteklenen parametreleri tek tek listeleyin.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("catalog-list", policy => policy
.Expire(TimeSpan.FromSeconds(30))
.SetVaryByRouteValue("tenantId")
.SetVaryByQuery("page", "pageSize", "sort")
.Tag("catalog-list"));
});
var app = builder.Build();
app.UseOutputCache();
app.MapGet("/api/tenants/{tenantId}/products", GetProducts)
.CacheOutput("catalog-list");Dil bazlı ürün adı dönüyorsanız Accept-Language başlığının ham değerini doğrudan varyasyon anahtarı yapmak risklidir; istemciler tr-TR,tr;q=0.9 gibi farklı ama eşdeğer diziler gönderir. İstek başında dili uygulamanın desteklediği sabit kümeye normalize edin ve yalnızca normalize edilmiş kültürle ayrı route üretin, örneğin /tr/api/.... Aynı nedenle User-Agent, Authorization ve tüm header'lar üzerinden varyasyon yapmak cache'i fiilen devre dışı bırakacak kadar çok anahtar üretir.
csharp eğitimi veya c# eğitimi laboratuvarında her policy için bir anahtar matrisi yazın: aynı tenant/page/sort iki kez çağrıldığında hit, tenant veya page değiştiğinde miss bekleyin. Bu testi WebApplicationFactory<Program> ile integration test olarak çalıştırın; yalnızca unit testte policy builder zincirinin çağrıldığını doğrulamak, middleware sırası veya endpoint metadata hatalarını yakalamaz.
C# kursu: tag ile geçersizleştirme ve yazma sonrası tutarlılık
Süre dolumunu tek geçersizleştirme mekanizması kabul etmeyin. Bir ürün fiyatı değiştiğinde 30 saniye boyunca eski fiyatın gösterilmesi iş kuralını ihlal ediyorsa, yazma işleminden sonra tag'i temizleyin. IOutputCacheStore.EvictByTagAsync, o tag ile ilişkilendirilmiş tüm response'ları siler; ancak tarayıcı veya CDN üzerindeki bağımsız cache'leri silmez. Bu nedenle uygulama Output Cache TTL'i ile gönderdiğiniz Cache-Control başlığını birbirinden bağımsız tasarlayın.
app.MapPut("/api/products/{id:guid}/price", async (
Guid id,
ChangePrice request,
CatalogDbContext db,
IOutputCacheStore outputCache,
CancellationToken ct) =>
{
var product = await db.Products.SingleOrDefaultAsync(x => x.Id == id, ct);
if (product is null) return Results.NotFound();
product.ChangePrice(request.Price);
await db.SaveChangesAsync(ct);
await outputCache.EvictByTagAsync("catalog-list", ct);
return Results.NoContent();
});Yukarıdaki akışta kritik edge case şudur: veritabanı commit olur, süreç cache temizlemeden önce çökerse eski response TTL sonuna kadar kalır. Çok instance'lı sistemde bunu transaction içine uzak cache çağrısı koyarak çözmeye çalışmayın; ağ çağrısı transaction süresini uzatır ve yine atomiklik sağlamaz. Bunun yerine değişiklikle aynı transaction'da bir outbox kaydı yazın, ayrı worker bu kaydı tüketip EvictByTagAsync çağrısını tekrar deneyebilsin. entity framework eğitimi kapsamında outbox tablosuna benzersiz event ID eklemek, worker yeniden başladığında aynı invalidation olayının güvenle tekrar işlenmesini sağlar.
Tag adı statiktir: catalog-list tüm tenant kataloglarını temizler. Bu, düşük yazma oranında kabul edilebilir bir basitliktir; yüzlerce tenant ve sık fiyat güncellemesinde gereksiz cold miss üretir. Tenant bazında hedefli temizleme gerekiyorsa statik tag yerine tenant kimliğini cache key'e dahil eden, tag ilişkisini de tenant bazında yöneten özel bir IOutputCachePolicy ve store tasarlayın. Önce dotnet-counters ile miss sonrası veritabanı yükünü ölçmeden bu karmaşıklığı eklemeyin.
microsoft teknolojileri eğitimi: sıcak ve soğuk cache ölçümü
Output Cache değişikliğini 'hızlandı' diye değerlendirmeyin. Ölçümde aynı veri seti, aynı bağlantı sayısı ve sabit bir istek hızı kullanın. Önce uygulamayı yeniden başlatıp ilk 60 saniyeyi cold cache olarak ölçün. Ardından 10 saniyelik ısınma çalıştırın ve 60 saniyelik warm cache ölçümünü alın. bombardier p50, p95 ve p99 gecikmelerini raporladığı için yalnızca ortalama gecikmeye bakmaktan daha güvenlidir.
# Sabit 400 RPS ile warm-cache ölçümü
bombardier -c 64 -d 60s -r 400 -H 'Accept: application/json' 'https://localhost:5001/api/tenants/acme/products?page=1&pageSize=20&sort=name'
# Çalışan süreçte GC ve allocation gözlemi
dotnet-counters monitor -p $PID System.Runtime
# CPU örneklemesi ile handler'ın gerçekten kaybolduğunu doğrulama
dotnet-trace collect -p $PID --profile cpu-sampling -o outputcache.nettraceÖnce-sonra karşılaştırmasında yalnızca p95'i değil, System.Runtime içindeki allocation rate, Gen 0 collection sayısı ve working set değerlerini aynı RPS'de kaydedin. Cache hit'te endpoint delegate, EF Core ve System.Text.Json çalışmadığından allocation rate'in düşmesi beklenir. Düşmüyorsa muhtemel nedenler şunlardır: cache anahtarının her istekte değişmesi, response'un cache uygun olmaması veya request'in authorization/cookie gibi policy tarafından elenmesi. dotnet-trace report outputcache.nettrace topN -n 20 ile iki profilde en pahalı methodları karşılaştırın; warm profilde sorgu materialization methodlarının üst sıralarda kalması hit alınmadığının somut işaretidir.
blazor eğitimi ve istemci cache'i ile Output Cache sınırı
Blazor Server veya Blazor WebAssembly istemcisi aynı katalog API'sini çağırsa bile server-side Output Cache sadece HTTP response'unu tekrar kullanır; component state'ini veya kullanıcının tarayıcısındaki listeyi güncellemez. blazor eğitimi örneğinde fiyat güncelleme sonrası istemcide açık listenin ne zaman yenileneceğini açıkça belirleyin: başarılı PUT'tan sonra ilgili sorguyu yeniden çağırın ya da SignalR olayıyla query cache'ini geçersizleştirin. İstemcinin rastgele eklediği nocache=GUID parametresini server policy'sinde varyasyon olarak kabul etmek ise her navigasyonda yeni Output Cache girdisi üretir.
Bir csharp kursu egzersizi olarak API response'una ETag ekleyip istemcinin If-None-Match göndermesini test edin, fakat ETag ile Output Cache'i aynı mekanizma sanmayın. ETag, istemcinin zaten indirdiği temsil için 304 almasını sağlar; Output Cache ise uygulamanın temsil üretme işini atlar. CDN kullanıyorsanız Cache-Control: public, max-age=... yalnızca gerçekten public endpoint'lerde gönderilmeli, tenant veya yetki bilgisini URL dışında taşıyan response'larda gönderilmemelidir.
İlgili Eğitim
YTÜSEM İlgili Eğitim
.NET Core ReactJS FullStack Eğitimi (Yıldız Teknik Üniversitesi SEM)
Sık Sorulan Sorular
.net core eğitimi kapsamında Output Cache mi Response Caching middleware mi kullanılmalı?
Endpoint bazlı TTL, query-route-header varyasyonu, tag ve programatik invalidation gerekiyorsa Output Cache kullanın. Response Caching middleware esas olarak istemci HTTP cache direktiflerine davranır. Kararı doğrulamak için aynı endpoint'e Cache-Control header'ı ile ve headersız istek atın, sonra Output Cache tag eviction sonrası response'un yeniden üretildiğini integration test ile gözlemleyin.
asp.net core eğitimi için Output Cache çoklu instance ortamında nasıl test edilir?
Varsayılan bellek içi store process başınadır; iki pod aynı URL için farklı cache içeriği tutabilir. Test ortamında iki instance'ı load balancer arkasında çalıştırın, bir instance'ta cache'i ısıtın ve diğerine yönlendirilmiş istekte miss olup olmadığını loglayın. Paylaşımlı store yazacaksanız GetAsync, SetAsync ve tag eviction ilişkilerini atomik yöneten bir IOutputCacheStore uygulaması gerekir; sadece response byte'larını Redis'e koymak tag temizliğini çözmez.
c# eğitimi sırasında Output Cache hit oranını nasıl ölçebilirim?
Uygulama loglarına endpoint, policy adı ve hit-miss sonucu için yapılandırılmış alan ekleyin; sonra bu alanlardan hit / (hit + miss) oranını endpoint ve tenant bazında hesaplayın. Ardından bombardier ile sabit RPS çalıştırıp hit oranını p95 ve dotnet-counters allocation rate ile birlikte kaydedin. Yüksek hit oranına rağmen p95 değişmiyorsa bağlantı havuzu, downstream proxy veya response gövdesi boyutu gibi cache dışı maliyetleri dotnet-trace ile inceleyin.
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.


