Ünite 8 / 11

Hız Limitleri ve Dayanıklı Hata Yönetimi

Kazanimlar:

  • Hız limitlerini (RPM/ITPM/OTPM) ve 429 hatasını yorumlayabilir
  • Üstel geri çekilme (exponential backoff) ve retry-after ile yeniden deneme uygular
  • Yaygın HTTP hata kodlarını (400/401/429/500/529) doğru sınıflandırıp ele alır

Üretim ortamında hiçbir API her zaman kusursuz yanıt vermez. Bazen çok hızlı istek gönderirsiniz ve limite takılırsınız; bazen sunucu geçici olarak yoğundur; bazen isteğiniz baştan hatalıdır. Sağlam bir entegrasyonu amatör bir denemeden ayıran şey, bu durumları öngörülü ve otomatik ele almasıdır. Bu ünitede hız limitlerini (RPM/ITPM/OTPM), 429 hatasını, üstel geri çekilmeyle yeniden denemeyi ve yaygın HTTP hata kodlarının doğru sınıflandırılmasını öğreneceksiniz. Amaç: bir kullanıcının hiç fark etmeyeceği kadar dayanıklı bir akış kurmak.

Hız Limitleri Nedir?

Sağlayıcı, bir anahtarın belli bir sürede ne kadar iş yapabileceğini sınırlar. Bu koruma; hem altyapıyı hem sizi ani maliyet patlamalarından korur. Üç yaygın limit türü vardır:

  • RPM (Requests Per Minute): Dakikadaki istek sayısı.
  • ITPM (Input Tokens Per Minute): Dakikada işlenebilen girdi token'ı.
  • OTPM (Output Tokens Per Minute): Dakikada üretilebilen çıktı token'ı.

Bu limitlerden herhangi birini aşarsanız sağlayıcı isteği reddeder ve 429 hata kodu döner. Limitler genellikle hesap seviyenize (tier) göre değişir ve zamanla yükseltilebilir.

İpucu: Limite yaklaştığınızı yanıt başlıklarından izleyebilirsiniz. Çoğu sağlayıcı x-ratelimit-remaining-* gibi başlıklarla kalan kotanızı bildirir. Bu değerleri izleyip trafiği önden yavaşlatmak (throttle), 429 almadan sorunu önlemenin en olgun yoludur.

429 ve Üstel Geri Çekilme

429 (rate limit) geçici ve yeniden denenebilir (retryable) bir hatadır. Doğru tepki, isteği bir süre bekleyip tekrar denemektir. Ama sabit bir bekleme yeterli değildir; herkes aynı anda tekrar denerse limit yine dolar. Çözüm üstel geri çekilmedir (exponential backoff): her başarısız denemede bekleme süresini katlayarak artırmak.

# Üstel geri çekilme mantığıdeneme 1 → 429 → 1 sn bekledeneme 2 → 429 → 2 sn bekledeneme 3 → 429 → 4 sn bekledeneme 4 → 429 → 8 sn bekle (+ küçük rastgele "jitter")... en fazla N denemeden sonra vazgeç ve raporla

Buna küçük bir rastgelelik (jitter) eklemek, aynı anda tekrar denemeye çalışan isteklerin çarpışmasını önler. Ayrıca 429 yanıtı çoğu zaman bir `retry-after` başlığı taşır: "şu kadar saniye sonra tekrar dene". Bu başlığa saygı göstermek, körlemesine beklemekten daha isabetlidir.

Dikkat: 429 alınca "daha çok istek göndererek zorlamak" durumu kötüleştirir; limit dolmaya devam eder ve hiçbir istek geçmez. Doğru tepki geri çekilmedir, hız artışı değil. İyi haber: çoğu resmi SDK 429 ve sunucu hatalarını otomatik olarak geri çekilmeyle yeniden dener — kendi elle kurmadan önce SDK'nın bu davranışını kullanın.

HTTP Hata Kodlarını Sınıflandırmak

Her hata aynı değildir. Kritik ayrım: yeniden denenebilir mi, yoksa istek/kimlik sorunu mu?

Kod

Anlamı

Yeniden denenebilir?

Doğru tepki

400

Geçersiz istek (biçim/parametre hatası)

Hayır

İsteği düzeltin; aynısını tekrar göndermeyin

401

Kimlik doğrulama hatası (anahtar geçersiz/eksik)

Hayır

Anahtarı/başlığı düzeltin

403

Yetki yok (model/özelliğe erişim yok)

Hayır

İzinleri/kapsamı kontrol edin

404

Bulunamadı (yanlış model kimliği/uç nokta)

Hayır

Model kimliğini/adresi düzeltin

429

Hız limiti aşıldı

Evet

Geri çekilme + retry-after

500

Sunucu hatası

Evet

Geri çekilmeyle tekrar dene

529

Sunucu aşırı yüklü

Evet

Geri çekilmeyle tekrar dene

Altın kural: 429, 500 ve 529 geçicidir; geri çekilmeyle tekrar denenir. 400, 401, 403, 404 ise istek/kimlik sorunudur; tekrar denemek çözmez, üstelik boşa istek harcar. Kodunuz bu iki grubu ayırt etmelidir.

Adım Adım: Dayanıklı Çağrı

  1. İsteği gönderin. Başarılıysa devam.
  2. Hata kodunu sınıflandırın. Yeniden denenebilir mi?
  3. Denenebilirse: retry-after'a uy, üstel geri çekilme + jitter uygula, sınırlı sayıda dene (ör. en fazla 5).
  4. Denenemezse: Düzelt (biçim/anahtar) ve durdur; aynı hatalı isteği döngüde tekrar etme.
  5. Vazgeçme durumunu ele al. N denemeden sonra hâlâ başarısızsa, kullanıcıya nazik bir mesaj göster ve olayı kaydet (11. ünite izleme).

# Sağlam çağrı sözde-kodudene = 0tekrar: yanıt = istek_at() eğer yanıt.başarılı: dön yanıt eğer yanıt.kod in [429, 500, 529] ve dene < 5: bekle = retry_after ?? (2^dene sn + jitter) uyu(bekle); dene += 1; git tekrar eğer yanıt.kod in [400, 401, 403, 404]: hata_kaydet(yanıt); dön "istek düzeltilmeli" dön "kalıcı hata, sonra dene"

# Kullanıcıya nazik geri dönüş (yeniden deneme tükenince)"Şu an yoğunluk var, isteğinizi işleyemedim. Birazdan tekrar deneyinveya talebinizi kaydettim, hazır olunca size döneceğim."

Zayıf prompt / Güçlü prompt (burada: hata mesajı tasarımı)

# ZAYIF (ham hatayı kullanıcıya gösterir)"Error 429: rate_limit_error"

# GÜÇLÜ (kullanıcı dostu, güven veren, eylem öneren)"Sistemde geçici bir yoğunluk oluştu. Talebinizi güvenle aldık ve otomatik olaraktekrar deneniyor. Bir sonuç birkaç saniye içinde görünmezse sayfayı yenileyebilirsiniz."

Ham teknik hatayı son kullanıcıya göstermek hem güveni sarsar hem güvenlik açığı olabilir. Hataları içeride sınıflandırıp kullanıcıya sakin, eyleme yönelten bir mesaj verin; teknik ayrıntıyı yalnızca kayıtlara yazın.

Üç Mini Vaka

Vaka 1 — Trafik patlamasında çöken bot. Bir müşteri hizmetleri botu kampanya günü ani trafikte 429 aldı; kodda yeniden deneme yoktu, her hata doğrudan kullanıcıya "hata" olarak yansıdı. Üstel geri çekilme + retry-after eklediler; aynı trafikte istekler birkaç saniye gecikmeyle geçti, kullanıcı hiçbir hata görmedi.

Vaka 2 — 400'ü döngüde denemek. Bir entegrasyon, geçersiz bir model kimliği yüzünden 404 alıyor ama tüm hataları "geçici" sayıp sonsuz döngüde tekrar deniyordu; hem log şişti hem gereksiz yük oluştu. Hata sınıflandırması eklediler: 404 kalıcı kabul edilip döngü durduruldu ve model kimliği düzeltildi. Ders: her hatayı yeniden denemeyin.

Vaka 3 — Limiti önden yönetmek. Bir veri zenginleştirme işi sürekli 429 sınırında çalışıyordu. x-ratelimit-remaining başlığını izleyip trafiği kotaya göre yavaşlattılar (throttle). Böylece hiç 429 almadan, limitin hemen altında istikrarlı bir hız tutturdular; iş daha öngörülebilir ve hızlı bitti.

Sık yapılan hatalar

  • 429'da hız artırmak: Durumu kötüleştirir; geri çekilmeye geçin.
  • Her hatayı yeniden denemek: 400/401/404 kalıcıdır; tekrar denemek boşa yüktür.
  • Sabit bekleme kullanmak: Çarpışma yaratır; üstel + jitter kullanın.
  • `retry-after`'ı yok saymak: Sağlayıcının söylediği süreye uymak en isabetlisidir.
  • Ham hatayı kullanıcıya göstermek: Güven sarsar, açık yaratır; içeride sınıflandırın.
  • Sınırsız yeniden deneme: Bir üst sınır (ör. 5 deneme) koyun; sonra nazikçe vazgeçin.

Daha Derine: Kuyruk, Eşzamanlılık ve Devre Kesici

Tek bir isteğin dayanıklılığı ilk adımdır; asıl olgunluk, çok sayıda isteği limitlere çarpmadan yönetmektir. Burada üç kavram devreye girer.

Kuyruk (queue): İstekleri anında değil, kontrollü bir hızda göndermek için bir kuyruğa koyarsınız. Kuyruk, ani trafik patlamalarını yumuşatır: 1.000 istek bir anda gelse bile kuyruk onları limitin altında kalacak bir hızda salar. Böylece 429'u önlersiniz, sonra düzeltmekle uğraşmazsınız.

Eşzamanlılık sınırı (concurrency limit): Aynı anda kaç isteğin "havada" olduğunu sınırlarsınız. Sınırsız paralel istek, RPM ve TPM limitlerini hızla doldurur. Makul bir eşzamanlılık tavanı (ör. aynı anda en fazla 10 istek) hem limitleri korur hem sistemi öngörülebilir kılar.

Devre kesici (circuit breaker): Sağlayıcı sürekli 500/529 dönüyorsa, her isteği inatla denemek yerine bir süre için "devreyi keser" ve isteği hiç göndermeden hızlıca başarısız sayarsınız. Bir bekleme sonrası devreyi tekrar açıp deneme yaparsınız. Bu desen, geçici bir sağlayıcı arızasında sisteminizin kilitlenmesini önler.

Bu üçü birlikte, tek bir çağrının retry mantığının ötesinde, sistem düzeyinde dayanıklılık kurar. Küçük ölçekte SDK'nın otomatik yeniden denemesi yeter; ölçek büyüdükçe kuyruk, eşzamanlılık ve devre kesici vazgeçilmez olur. Hepsinin ortak amacı aynıdır: geçici bir sorunu kullanıcıya bir çökme olarak değil, birkaç saniyelik görünmez bir gecikme olarak yansıtmak.

Özetle

Hız limitleri (RPM/ITPM/OTPM) aşıldığında 429 döner; bu geçici bir hatadır ve retry-after ile üstel geri çekilme + jitter kullanılarak yeniden denenir. 500 ve 529 da geçicidir; 400/401/403/404 ise istek/kimlik sorunudur ve tekrar denemekle çözülmez. Dayanıklı bir akış, hataları bu iki gruba ayırır, sınırlı sayıda dener, limiti önden izleyip kullanıcıya sakin mesajlar gösterir.

Uygulama görevi

Bir entegrasyonunuzu düşünün. (1) Karşılaşabileceğiniz hata kodlarını listeleyip "yeniden denenebilir / kalıcı" diye ayırın. (2) Üstel geri çekilme planınızı yazın (başlangıç bekleme, katsayı, üst sınır, jitter). (3) retry-after başlığını nasıl kullanacağınızı belirtin. (4) Yeniden deneme tükendiğinde kullanıcıya gösterilecek nazik mesajı yazın.

Kontrol listesi

  • [ ] RPM/ITPM/OTPM limitlerini ve 429'u açıklayabiliyorum.
  • [ ] Üstel geri çekilme + jitter + retry-after mantığını uygulayabiliyorum.
  • [ ] Hata kodlarını yeniden denenebilir/kalıcı diye sınıflandırabiliyorum.
  • [ ] Her hatayı denememek gerektiğini biliyorum.
  • [ ] Ham hata yerine kullanıcıya sakin, eyleme yönelten mesaj gösterebiliyorum.