• 24.09.2026 21:23:13
  • Admin Admin

Bu asp.net core eğitimi, HttpClient isteklerinde timeout, retry ve circuit breaker sırasını Microsoft.Extensions.Http.Resilience ile kurmayı; idempotency risklerini ve k6 ile etkisini ölçmeyi ele alır.

ASP.NET Core Eğitimi: ResilienceHandler ile HTTP İstemci Dayanıklılığı

ASP.NET Core eğitimi: HttpClient için politikanın sınırını belirlemek

Bir asp.net core eğitimi içinde HttpClient retry ayarı genellikle tek satırlık bir eklenti gibi gösterilir; üretimde asıl karar, hangi çağrının yeniden gönderilebilir olduğudur. Katalog, kur veya profil gibi salt okunur GET çağrılarını ayrı bir named client altında toplayın. Ödeme oluşturma, sipariş onayı ve e-posta gönderme gibi POST çağrılarını aynı pipeline'a koymayın. Bunun teknik nedeni, ağdaki timeout'un sunucunun isteği işlemediğini değil, yanıtın istemciye dönemediğini göstermesidir. Bağımlılığı projeye eklemek için aşağıdaki komutu çalıştırın:

dotnet add package Microsoft.Extensions.Http.Resilience

Bir .net core eğitimi veya .net core kursu kapsamında bu ayrımın test edilebilir karşılığı, dış servisin URL'sini typed client içine gömmemektir. `IHttpClientFactory`, handler ömrünü yönettiği için DNS değişimlerini ve bağlantı havuzunu doğrudan `new HttpClient()` kullanımından daha doğru taşır. Ancak factory, mantıksal olarak hatalı retry politikasını düzeltmez. Örneğin `catalog-read` istemcisine yalnızca GET çağrısı yapan bir arayüz tanımlayın ve yazma operasyonları için ayrı bir client kullanın.

C# eğitimi: Toplam zaman bütçesi, deneme timeout'u ve circuit breaker sırası

Aşağıdaki pipeline'da ilk timeout tüm işlem için 3 saniyelik üst sınırdır. Circuit breaker retry'ın dışındadır; dolayısıyla breaker, üç başarısız denemeyi üç ayrı iş hatası olarak değil, tek bir mantıksal çağrının sonucu olarak değerlendirir. En içteki 700 ms timeout ise takılmış tek bir denemeyi keser. Stratejiler eklendikleri sırayla dıştan içe çalıştığından bu sıra değiştirilirse breaker örneklemindeki hata sayısı ve istemcinin bekleme süresi değişir.

using Microsoft.Extensions.Http.Resilience;
using Polly;
using Polly.CircuitBreaker;
using Polly.Retry;
using Polly.Timeout;

builder.Services.AddHttpClient("catalog-read", client =>
{
    client.BaseAddress = new Uri("https://catalog.internal/");
    client.DefaultRequestHeaders.Accept.ParseAdd("application/json");
})
.AddResilienceHandler("catalog-pipeline", pipeline =>
{
    // Disaridaki limit: retry ve bekleme dahil tum cagrinin butcesi.
    pipeline.AddTimeout(new TimeoutStrategyOptions
    {
        Timeout = TimeSpan.FromSeconds(3)
    });

    // Breaker, retry'in nihai sonucunu gorur.
    pipeline.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
    {
        FailureRatio = 0.50,
        MinimumThroughput = 20,
        SamplingDuration = TimeSpan.FromSeconds(30),
        BreakDuration = TimeSpan.FromSeconds(15)
    });

    pipeline.AddRetry(new HttpRetryStrategyOptions
    {
        MaxRetryAttempts = 2,
        Delay = TimeSpan.FromMilliseconds(150),
        BackoffType = DelayBackoffType.Exponential,
        UseJitter = true,
        ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
            .Handle<HttpRequestException>()
            .Handle<TimeoutRejectedException>()
            .HandleResult(response =>
                response.StatusCode == System.Net.HttpStatusCode.BadGateway ||
                response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable ||
                response.StatusCode == System.Net.HttpStatusCode.GatewayTimeout)
    });

    // Her tek denemenin kendi tavan suresi.
    pipeline.AddTimeout(new TimeoutStrategyOptions
    {
        Timeout = TimeSpan.FromMilliseconds(700)
    });
});

Bu yapıdaki kritik incelik, `429 Too Many Requests` yanıtını koşulsuz retry listesine eklememektir. Karşı servis `Retry-After` gönderiyorsa sabit 150 ms gecikme kota ihlalini büyütür. 429 için ya sağlayıcının verdiği yeniden deneme zamanını okuyup özel bir `DelayGenerator` yazın ya da çağrıyı başarısız sayıp üst katmandaki iş kuyruğuna erteleyin. csharp eğitimi ve csharp kursu materyallerinde sık görülen 'tüm 5xx kodlarını tekrar dene' kuralı, uzun süren 503 olaylarında bağlantı havuzu ile upstream kuyruğunu aynı anda şişirebilir.

C# kursu: POST retry, idempotency key ve EF Core kalıcılığı

Bir c# eğitimi ya da c# kursu örneğinde POST için retry gerekiyorsa, istemcinin aynı idempotency anahtarını her denemede koruması tek başına yeterli değildir. Sunucunun bu anahtarı kalıcı ve benzersiz bir kayıtla ilişkilendirmesi gerekir. Bellek içi `ConcurrentDictionary` çoklu pod dağıtımında çalışmaz; pod değişince aynı ödeme ikinci kez işlenebilir. `IdempotencyKey` tablosunda `ClientId + Key` için benzersiz indeks oluşturun ve yanıt gövdesi ile HTTP durumunu saklayın.

public sealed class IdempotencyRecord
{
    public long Id { get; set; }
    public required string ClientId { get; set; }
    public required string Key { get; set; }
    public required string ResponseJson { get; set; }
    public int StatusCode { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<IdempotencyRecord>()
        .HasIndex(x => new { x.ClientId, x.Key })
        .IsUnique();
}

Entity Framework eğitimi açısından burada önemli edge case, önce `AnyAsync` ile kontrol edip sonra insert yapmaktır. İki eşzamanlı istek ikisi de `false` görebilir. Doğru yarış kontrolü benzersiz indeksin veritabanında zorlanmasıdır: insert sırasında oluşan unique constraint ihlalini yakalayın, kaydı tekrar okuyun ve saklanmış yanıtı dönün. Bu nedenle idempotency kaydı ile iş verisini aynı veritabanı transaction'ında yazmak gerekir; aksi halde kayıt oluşturulup iş komutu başarısız olduğunda istemci sonsuza kadar hatalı bir sonucu tekrar alabilir.

Microsoft teknolojileri eğitimi: Retry maliyetini k6 ve dotnet-counters ile ölçmek

Retry'ın gecikme ve çağrı sayısına etkisini varsaymayın. Önce resilience handler kapalıyken, sonra yukarıdaki pipeline açıkken aynı senaryoyu çalıştırın. Uygulama process kimliğini `dotnet-counters ps` ile bulun, ardından kullanılabilir sayaç adlarını sürüm bağımlı tahminlerle değil `dotnet-counters list -p <PID>` komutuyla keşfedin. `System.Net.Http` altında başlatılan, başarısız olan ve eşzamanlı istek sayaçlarını yük testi boyunca kaydedin:

dotnet-counters monitor -p <PID> --counters System.Net.Http

Aşağıdaki k6 betiği normal trafikte upstream çağrısı başına retry patlaması olmadığını, hata enjeksiyonunda ise istemcinin toplam 3 saniyeyi aşmadığını doğrulamak için kullanılabilir. Test ortamında upstream proxy'siyle isteklerin yüzde 10'una 503 enjekte edin. Kabul kriterini somut tutun: normal akışta upstream istek sayısı uygulama isteği başına 1.15'i geçmesin, enjekte edilmiş hata akışında API'nin p95 süresi 3 saniyenin altında kalsın ve breaker açıkken upstream'e yeni bağlantı artışı gözlenmesin.

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

export const options = {
  vus: 40,
  duration: '2m',
  thresholds: {
    http_req_duration: ['p(95)<3000'],
    http_req_failed: ['rate<0.15']
  }
};

export default function () {
  const response = http.get('https://api.test.local/products/42');
  check(response, {
    'status is 200 or controlled failure': r => r.status === 200 || r.status === 503
  });
}

Bu önce-sonra karşılaştırmasında sadece API p95 değerine bakmak eksiktir. Retry, kullanıcı isteği sayısı sabitken upstream'e giden toplam çağrıyı artırır; bu artış upstream'in kuyruk süresini yükselttiğinde ilk baştaki geçici hata kalıcı bir kapasite olayına dönüşür. microsoft teknolojileri eğitimi için yararlı bir pratik, k6 sonuçlarını `System.Net.Http` sayaçları ve reverse proxy'nin 5xx oranıyla aynı zaman ekseninde saklamaktır.

Blazor eğitimi: UI iptali ile sunucu dayanıklılık politikasını ayırmak

Blazor eğitimi projelerinde kullanıcı sayfadan ayrıldığında UI katmanının `CancellationToken` ile isteği iptal etmesi doğrudur, fakat bu token'ı otomatik olarak iş kuyruğundaki kritik yazma komutuna taşımak tehlikelidir. Örneğin ödeme komutu için istemci bağlantısının kopması işin iptali anlamına gelmez. GET ekran çağrılarında `HttpContext.RequestAborted` token'ını typed client'a iletin; kalıcı komutlarda ise ayrı bir uygulama zaman bütçesi ve idempotency anahtarı kullanın. Böylece kullanıcı iptali, circuit breaker'ın upstream hatası gibi örneklemesine gereksiz başarısızlık eklemez.

Operasyonel olarak breaker açıldığında bunu 500'e çevirip gizlemeyin. `BrokenCircuitException` yakalandığında API sınırında 503 ve kısa bir `Retry-After` dönün; istemci de bu yanıtı yeni bir retry döngüsüne sokmasın. Bu davranışı entegrasyon testinde, test upstream'ini 20 çağrı boyunca 503 döndürecek şekilde kurarak doğrulayın: breaker açıldıktan sonra upstream çağrı sayısı sabitlenmeli, 15 saniyelik `BreakDuration` sonunda yalnızca sınırlı sayıdaki deneme akışı yapılmalıdır.

İlgili Eğitim

.NET Core Eğitimi

Sık Sorulan Sorular

.net core kursu projelerinde HttpClient retry kaç kez yapılmalı?

Sabit bir sayı seçmeyin. GET çağrısının toplam zaman bütçesini önce belirleyin. Örneğin 3 saniyelik bütçede 700 ms deneme timeout'u ve iki ek deneme, gecikme payıyla sığabilir. k6 ile normal akışta upstream çağrısı/istek oranını ve hata enjeksiyonunda p95'i ölçmeden `MaxRetryAttempts` değerini artırmayın.

csharp eğitimi için POST isteğinde retry güvenli hale nasıl getirilir?

İstemci her denemede aynı `Idempotency-Key` değerini göndermeli, sunucu ise bu anahtarı benzersiz veritabanı indeksiyle saklamalıdır. EF Core tarafında kontrol et-sona insert yapmayın; unique constraint ihlalini yakalayıp mevcut kaydın saklanmış durum kodu ve yanıtını döndürün.

asp.net core eğitimi sırasında circuit breaker neden retry'ın dışında konumlandırılır?

Breaker retry'ın dışındaysa üç denemeden oluşan başarısız işlem, breaker örneklemine tek mantıksal başarısızlık olarak girer. Breaker içerideyse her deneme örnekleme eklenir ve kısa süreli bir upstream dalgalanmasında beklenenden hızlı açılabilir. Pipeline sırasını entegrasyon testinde upstream çağrı sayısı ile doğrulayın.

entity framework eğitimi örneklerinde idempotency tablosu ne kadar süre tutulmalı?

Süreyi istemcinin en uzun retry penceresi, asenkron kuyruk gecikmesi ve iş gereksinimine göre belirleyin. Ödeme benzeri işlemlerde kayıtları birkaç dakikada silmek risklidir; gecikmiş bir istemci aynı anahtarla ikinci komutu gönderebilir. TTL temizliğini indeksli bir `CreatedAt` kolonu üzerinden batch job ile yapın ve silmeden önce denetim gereksinimlerini değerlendirin.

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