• 6.09.2026 21:23:17
  • Admin Admin

Bu asp.net core eğitimi rehberi, PartitionedRateLimiter ile kullanıcı, istemci ve rota bazlı limitleri; 429 sözleşmesini, proxy güvenini ve k6 ile önce-sonra yük ölçümünü ele alır.

ASP.NET Core Eğitimi: Partitioned Rate Limiting ile API Koruması

ASP.NET Core Eğitimi: Partitioned Rate Limiting için doğru anahtar

Rate limiting kararı, tek başına istek sayısından çok partition key seçimine bağlıdır. Kimliği doğrulanmış bir API'de User.Identity.Name, anonim uçlarda ise güvenilir biçimde elde edilmiş istemci IP'si uygun başlangıç noktasıdır. Sadece RemoteIpAddress kullanmak, NAT arkasındaki yüzlerce kullanıcıyı tek kotada toplar; sadece istemcinin yolladığı X-Forwarded-For başlığını kullanmak ise saldırganın key'i her istekte değiştirerek limiti atlamasına izin verir. Bir .net core eğitimi veya .net core kursu kapsamında bu ayrımın pratik sonucu, kimlik yoksa IP'ye, kimlik varsa kullanıcı kimliğine bölümlenmiş bir politika kurmaktır.

using System.Threading.RateLimiting;

builder.Services.AddRateLimiter(options =>
{
    options.AddPolicy<string>("write-per-subject", httpContext =>
    {
        var subject = httpContext.User.Identity?.IsAuthenticated == true
            ? httpContext.User.FindFirst("sub")?.Value
              ?? httpContext.User.Identity!.Name!
            : httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";

        return RateLimitPartition.GetTokenBucketLimiter(
            partitionKey: subject,
            factory: _ => new TokenBucketRateLimiterOptions
            {
                TokenLimit = 20,
                TokensPerPeriod = 10,
                ReplenishmentPeriod = TimeSpan.FromSeconds(1),
                AutoReplenishment = true,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit = 0
            });
    });
});

app.UseAuthentication();
app.UseRateLimiter();
app.UseAuthorization();

app.MapPost("/orders", CreateOrder)
   .RequireRateLimiting("write-per-subject");

Bu yapıdaki token bucket, ilk anda 20 isteklik kontrollü burst kabul eder ve sonrasında saniyede 10 token üretir. QueueLimit = 0 özellikle yazma uçlarında bilinçli bir tercihtir: kuyruk, bağlantı ve request body kaynaklarını tutar; doymuş bir veritabanına yeni bekleyen iş eklemek yerine istemciye hemen 429 dönmek daha öngörülebilir bir geri basınç oluşturur. csharp eğitimi ve csharp kursu içeriklerinde sık atlanan incelik, partition key'in sınırsız kardinaliteye sahip olmasıdır. Rastgele API anahtarı veya her istek için üretilen correlation id kullanılırsa limiter, her partition için durum oluşturur ve saldırı altında bellek tüketimi büyür.

C# Eğitimi: Proxy zinciri ve kimlikten önce gelen güven sınırı

Ters proxy arkasındaki uygulamada gerçek istemci adresi, yalnızca bilinen proxy'nin eklediği forwarded header'lardan okunmalıdır. UseForwardedHeaders rate limiter'dan önce çalışmazsa tüm trafik yük dengeleyicinin IP'si gibi görünür. Buna karşılık KnownNetworks veya KnownProxies tanımlamadan forwarded header'ları açmak, doğrudan uygulama portuna erişebilen bir istemcinin sahte IP göndermesine yol açar. c# eğitimi ve c# kursu seviyesinde üretim sistemlerinde bu middleware sırası, limiter algoritmasından daha kritik bir hata kaynağıdır.

using Microsoft.AspNetCore.HttpOverrides;
using System.Net;

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                               ForwardedHeaders.XForwardedProto;
    options.KnownProxies.Add(IPAddress.Parse("10.20.0.15"));
    options.ForwardLimit = 1;
});

var app = builder.Build();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseRateLimiter();
app.UseAuthorization();

ForwardLimit = 1, uygulamanın önünde tek güvenilen proxy olduğu varsayımını kodlaştırır. CDN + ingress + service mesh gibi çoklu hop zincirinde sayı ve güvenilen ağlar altyapı topolojisine göre açıkça listelenmelidir. Bu ayarları doğrulamak için staging ortamında proxy üzerinden ve doğrudan pod adresine iki curl -H "X-Forwarded-For: 203.0.113.7" isteği gönderin; ikinci isteğin sahte adresi partition key olarak kabul etmediğini uygulama debug logundan kontrol edin. microsoft teknolojileri eğitimi kapsamında bu test, ağ varsayımını yalnızca dokümana değil çalıştırılabilir bir kontrole bağlar.

.NET Core Eğitimi: Token bucket değerlerini k6 ve dotnet-counters ile ölçmek

Limit değerini '20 istek' diye sabitlemeden önce, limit uygulanmamış sürüm ile limit uygulanmış sürümü aynı yük profili altında karşılaştırın. k6 senaryosunda aynı kullanıcı kimliğiyle 100 VU kullanmak, partition başına baskıyı görünür kılar. Önce p95 gecikme, hata oranı, saniye başına tamamlanan istek ve 429 oranını kaydedin; sonra yalnızca TokenLimit, TokensPerPeriod ve QueueLimit değişmiş sürümü çalıştırın. Başarı ölçütü 429 sayısının düşük olması değildir: kabul edilen isteklerin p95 değeri ve veritabanı bağlantı havuzu beklemesinin sınır altında kalmasıdır.

import http from 'k6/http';
import { check } from 'k6';

export const options = {
  scenarios: {
    same_subject_burst: {
      executor: 'constant-vus',
      vus: 100,
      duration: '60s'
    }
  },
  thresholds: {
    'http_req_duration{status:201}': ['p(95)<400'],
    'http_req_failed': ['rate<0.95']
  }
};

export default function () {
  const response = http.post(
    'https://staging.example.test/orders',
    JSON.stringify({ sku: 'A-42', quantity: 1 }),
    { headers: { 'Content-Type': 'application/json', Authorization: 'Bearer test-user-1' } }
  );
  check(response, { '201 veya 429': r => r.status === 201 || r.status === 429 });
}

Yük testi sırasında işlem kimliğini bulup sayaçları 1 saniyelik aralıkla toplayın: dotnet-counters monitor --process-id <pid> System.Runtime Microsoft.AspNetCore.Hosting. Limit öncesi ve sonrası için threadpool-queue-length, gc-heap-size, alloc-rate ve aktif istek sayısını aynı CSV zaman penceresinde kıyaslayın. 429 üretilirken thread pool kuyruğu büyümeye devam ediyorsa limiter endpoint'e yeterince erken uygulanmıyor, ya da pahalı kimlik doğrulama ve gövde okuma işlemleri limitlemeden önce gerçekleşiyordur. entity framework eğitimi yapan ekipler ayrıca SQL bağlantı havuzu metriklerini izlemelidir; limiter'ın değeri, reddedilen isteğin EF Core sorgusu ve bağlantı kiralaması yapmamasında ortaya çıkar.

ASP.NET Core'da 429 sözleşmesi, Retry-After ve kuyruk davranışı

429 yanıtı yalnızca durum kodu olmamalıdır. Token bucket lease'i RetryAfter metadatası taşıyorsa istemciye standart Retry-After başlığını iletin ve makine tarafından okunabilir bir hata gövdesi üretin. Bu, özellikle otomatik retry kullanan istemcilerin sabit aralıkla tekrar deneyip aynı partition'ı tekrar doygunlaştırmasını engeller. Retry-After hesaplanamayan limiter türlerinde başlığı tahmin ederek eklemeyin; yanlış kısa süre, retry fırtınası üretir.

using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;

builder.Services.AddRateLimiter(options =>
{
    options.OnRejected = async (context, cancellationToken) =>
    {
        var response = context.HttpContext.Response;
        response.StatusCode = StatusCodes.Status429TooManyRequests;

        if (context.Lease.TryGetMetadata(
                MetadataName.RetryAfter, out TimeSpan retryAfter))
        {
            response.Headers.RetryAfter =
                Math.Ceiling(retryAfter.TotalSeconds).ToString();
        }

        await response.WriteAsJsonAsync(new
        {
            type = "https://api.example.test/problems/rate-limit",
            title = "Rate limit exceeded",
            status = 429,
            traceId = context.HttpContext.TraceIdentifier
        }, cancellationToken);
    };
});

Blazor WebAssembly veya sunucu tarafı bir istemcide retry handler, 429 için yalnızca Retry-After varsa beklemeli; yoksa sınırlı sayıda jitter'lı geri çekilme kullanmalıdır. blazor eğitimi örneklerinde yaygın hata, kullanıcı bir formu çift tıkladığında her 429 yanıtını hemen tekrar göndermektir. Aynı ilke, idempotency key ile birlikte uygulanmalıdır: limiter isteği kabul etmiş fakat ağ yanıtı düşmüşse körlemesine yeni sipariş yaratmak yerine aynı Idempotency-Key ile sonucu sorgulamak gerekir.

Rate limiter politikalarını entegrasyon testiyle kilitlemek

Politikanın gerçekten istenen partition'a ayrıldığını doğrulamak için WebApplicationFactory ile aynı kullanıcı adına ait ardışık istekleri test edin. Testte limiter ayarını çok küçük tutmak, zaman bağımlılığını azaltır: 2 token, uzun yenileme periyodu ve 0 kuyruk ile üçüncü isteğin 429 dönmesi deterministik hale gelir. Gerçek zamanlı Task.Delay ile yenileme bekleyen testler CI makinesinde kararsızlaşır; bu nedenle reddetme yolunu yenileme gerektirmeden sınayın.

[Fact]
public async Task Same_subject_is_rejected_after_token_limit()
{
    await using var app = new ApiFactory();
    using var client = app.CreateClient();

    client.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Test", "subject-42");

    var first = await client.PostAsJsonAsync("/orders", new { sku = "A-42" });
    var second = await client.PostAsJsonAsync("/orders", new { sku = "A-42" });
    var third = await client.PostAsJsonAsync("/orders", new { sku = "A-42" });

    Assert.Equal(HttpStatusCode.Created, first.StatusCode);
    Assert.Equal(HttpStatusCode.Created, second.StatusCode);
    Assert.Equal(HttpStatusCode.TooManyRequests, third.StatusCode);
    Assert.True(third.Headers.Contains("Retry-After"));
}

Test matrisi en az dört satır içermelidir: aynı subject ile kota aşımı, farklı subject'lerin birbirini etkilememesi, anonim IP partition'ı ve sahte forwarded header'ın reddi. asp.net core eğitimi içinde bu testleri endpoint davranışının parçası saymak gerekir; aksi halde authentication claim adı değiştiğinde partition key sessizce unknown değerine düşebilir ve tüm kullanıcılar aynı sınıra sıkışır.

İlgili Eğitim

.NET Core Eğitimi

Sık Sorulan Sorular

.net core kursu projelerinde Fixed Window mi Token Bucket mi kullanılmalı?

Kısa süreli kontrollü burst kabul etmek istiyorsanız Token Bucket seçin: örneğin 20 başlangıç token'ı ve saniyede 10 yenileme ile ani istemci dalgası karşılanır. Fixed Window, pencere sınırında iki ardışık pencereden toplamda beklenenden fazla istek kabul edebilir. Kararı k6 ile aynı partition üzerinde ölçün ve kabul edilen isteklerin p95 süresini karşılaştırın.

csharp eğitimi sırasında ASP.NET Core rate limiting neden kullanıcı adına göre partition edilmelidir?

JWT içindeki sabit bir subject claim'i, aynı kullanıcının farklı IP'lerden yaptığı istekleri tek kotada toplar. IP tabanlı anahtar ise kurumsal NAT arkasındaki farklı kullanıcıları yanlışlıkla aynı kotaya koyabilir. Uygulamada doğrulanmış subject claim'ini kullanın, anonim uçlar için ise yalnızca KnownProxies ile güvenilen forwarded IP'ye geri düşün.

entity framework eğitimi alan ekipler rate limiter'ı EF Core sorgusundan önce nasıl uygular?

Endpoint'e RequireRateLimiting("write-per-subject") ekleyin ve app.UseRateLimiter() middleware'ini endpoint yürütülmeden önce yerleştirin. k6 testi sırasında 429 alan isteklerin EF Core command logu üretmediğini doğrulayın. SQL komutları 429 ile birlikte görünüyorsa sorgu, limiter kararından önce çalışan başka bir middleware veya handler içinde tetikleniyordur.

blazor eğitimi örneklerinde 429 yanıtı alındığında istemci ne yapmalı?

HttpResponseMessage içindeki Retry-After değerini okuyun, kullanıcıya gönderimin ertelendiğini gösterin ve aynı isteği jitter olmadan sürekli tekrar etmeyin. Yazma işlemlerinde sabit bir idempotency key kullanın; ağ hatası ile 429 yanıtını aynı retry politikasına koymak çift kayıt üretebilir.

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