Hayal edin: Bir siteye istek gönderen bir istemci yazdınız ve her şey çalışıyor. Sonra aniden hatalar yağmaya başlıyor, çalışanlar takılıp kalıyor ve sunucu gizemli 429 koduyla yanıt veriyor. Tanıdık geldi mi? O zaman bu kılavuz tam size göre. İlk sorunda panik yapmayan, aksine kibar ve dayanıklı davranan bir HTTP istemcisini nasıl inşa edeceğimizi adım adım inceleyeceğiz.

Giriş: Neden 429 Bir Hata Değil, Bir Sinyaldir

Birçok geliştirici 429 kodunu gördüğünde bozuldu diye düşünür. Aslında sunucu size çok net bir şey söylüyor: çok fazla istek gönderiyorsunuz, yavaşlayın. Bu kalıcı bir ret veya blokaj değil. Sadece temponuzu düşürmeniz için bir rica. Ve eğer bu ricayı doğru duyarsanız, istemciniz güvenilir hale gelir.

Okuyucu Sonuçta Ne Elde Edecek?

Bu kılavuzun sonunda, birkaç önemli şeyi yapabilen çalışır bir HTTP istemciniz olacak. 429 kodunu doğru işleyecek ve Retry-After başlığına saygı gösterecek. Tekrar fırtınası yaratmamak için jitter ile exponansiyel backoff kullanacak. Hedef sunucuyu boğmamak için paralelliği sınırlayacak. Ve doğru zaman aşımları sayesinde takılıp kalmayacak.

Üç dilde hazır kod parçaları alacaksınız: Python (httpx kütüphanesi ve urllib3 Retry ile), Node.js ve Go. Her bir parçayı kendi projenize ekleyip ihtiyacınıza göre uyarlayabilirsiniz.

Bu Kılavuz Kimler İçin?

Kılavuz, basit HTTP istekleri yapmayı bilen ancak henüz prodüksiyon yüküyle karşılaşmamış başlangıç seviyesindeki geliştiriciler için hazırlanmıştır. Ancak ileri düzey konular da var: circuit breaker, metrikler, kontrollü bozulma. Bir ayrıştırıcı, harici bir API ile entegrasyon veya dış kaynaklara istek yapan bir hizmet yazıyorsanız, bu materyal size birçok uykusuz gece kazandıracak.

Önceden Bilmeniz Gerekenler

HTTP isteği ve HTTP yanıtının ne olduğunu anlamanız yeterli. Durum kodlarını (örneğin 200 başarı, 404 sayfa bulunamadı) bilmek faydalı olur. Python, JavaScript veya Go dillerinden en az birine temel düzeyde aşina olmanız işinizi kolaylaştıracak. Derin ağ bilgisi gerekmez – her şeyi basit kelimelerle açıklayacağız.

Ne Kadar Sürecek?

Teoriyi okuyup anlamak yaklaşık 40 dakika. Adım adım temel bir istemciyi toplamak yaklaşık bir saat. Tüm korumalar, metrikler ve testlerle birlikte tam uygulama yaklaşık üç saat. Acele etmeyin: Her adımı yavaşça anlamak, anlamadığınız kodu hızlıca kopyalamaktan daha iyidir.

İpucu: Kılavuzu açık bir kod düzenleyiciyle okuyun. Örnekleri canlı bir prodüksiyon hizmetinde değil, test amaçlı bir uç noktada hemen deneyin.

Ön Hazırlık

Kod yazmadan önce çalışma ortamımızı hazırlayalım. Biraz zaman alacak ancak ileride kafa karışıklığını önleyecek.

Gerekli Araçlar

  • Dillerden biri ve ortamı: Python 3.11 veya üzeri, ya da Node.js 20 veya üzeri, ya da Go 1.22 veya üzeri.
  • Bir kod düzenleyici – VS Code gibi herhangi biri iş görür.
  • Betikleri çalıştırmak için bir terminal.
  • Farklı yanıt kodları döndürebilen bir test HTTP hizmetine internet erişimi.

Python için Kurulum

  1. Terminalde python --version yazıp Enter'a basarak Python sürümünüzü kontrol edin.
  2. python -m venv venv komutuyla sanal bir ortam oluşturun.
  3. Etkinleştirin: Windows'ta venv\Scripts\activate, macOS ve Linux'ta source venv/bin/activate.
  4. pip install httpx urllib3 requests komutuyla kütüphaneleri yükleyin.

Node.js için Kurulum

  1. node --version ile sürümü kontrol edin.
  2. Proje klasörü oluşturun ve içine girin.
  3. npm init -y ile projeyi başlatın.
  4. Node.js 20'den itibaren yerleşik fetch hazır, temel istemci için ek paket gerekmez.

Go için Kurulum

  1. go version ile sürümü kontrol edin.
  2. Bir klasör oluşturun ve go mod init myclient ile modülü başlatın.
  3. Standard net/http kütüphanesi yeterli, harici paket zorunlu değil.

Yedekler ve Güvenlik

⚠️ Dikkat: Yeni istemcinizi asla doğrudan önemli bir prodüksiyon hizmetinde test etmeyin. Önce kontrolünüz altında olan bir test uç noktası veya yerel bir sunucu kullanın. Aksi takdirde agresif tekrarlar başka bir hizmete zarar verebilir ve bloke edilmenize yol açabilir.

Mevcut bir projeyi geliştiriyorsanız, dosyanın bir kopyasını alın veya sürüm kontrol sisteminde ayrı bir dal oluşturun. Böylece değişiklikleri her zaman geri alabilirsiniz.

✅ Kontrol: Seçtiğiniz dili kurdunuz, projeyi oluşturdunuz ve test betiğinin hatasız çalıştığından emin oldunuz. Şimdi teoriye geçebiliriz.

Temel Kavramlar Basit Dille

İstemciyi sağlam bir şekilde inşa etmek için birkaç anahtar terimi anlamanız gerekir. Karmaşık kelimeler kullanmadan açıklayalım.

403, 407, 429 ve 503 Kodları Ne Anlama Gelir?

Bu dört kodu karıştırmak kolaydır ancak davranışları farklıdır ve çözümleri de farklıdır.

  • Kod 429 Too Many Requests – Sunucu, istek limitinizi aştığınızı söyler. Bu geçicidir. Yavaşlamanız ve daha sonra tekrar denemeniz gerekir.
  • Kod 403 Forbidden – Erişim yasak. Genellikle hızla ilgili değil, yetkilerle ilgilidir: yanlış anahtar, yetkilendirme eksikliği, bölge kısıtlaması. İsteği değiştirmeden tekrarlamak genellikle işe yaramaz.
  • Kod 503 Service Unavailable – Sunucu geçici olarak aşırı yüklü veya bakımda. Tıpkı 429 gibi geçicidir ve daha sonra tekrar denemek işe yarayabilir.
  • Kod 407 Proxy Authentication Required – İşte önemli bir nüans. Bu kod hedef siteden değil, proxy sunucusundan gelir. Proxy'nin yetkilendirme istediği ve sizin bunu sağlamadığınız veya yanlış sağladığınız anlamına gelir.

⚠️ Dikkat: 407 kodu IP rotasyonu veya backoff ile tedavi edilemez. Bu, istemci yapılandırmanızda bir hatadır, özellikle de proxy için yanlış kimlik bilgileri. Proxy ayarlarını düzeltmeden hiçbir tekrar işe yaramaz.

429 ve 403 Arasındaki Fark

Basit bir kuralı hatırlayın. 429 miktarla ilgilidir: çok sık yapıyorsunuz. 403 hakla ilgilidir: size genel olarak izin yok. 429'da aradan sonra tekrar denemek sorunu çözer. 403'te koşulları değiştirmeden tekrar çözüm olmaz – anahtarı, başlıkları veya yaklaşımı değiştirmeniz gerekir.

Retry-After ve X-RateLimit Başlıkları

Kibar sunucular ne zaman geri dönebileceğinizi belirtir. Retry-After başlığı, isteği kaç saniye sonra tekrarlamanız gerektiğini söyler. Bazen saniye sayısı, bazen belirli bir tarih. İstemciniz bu başlığa saygı göstermek zorundadır: Sunucu 10 saniye bekle dediyse, 1 saniye sonra tekrar denemek durumu daha da kötüleştirir.

X-RateLimit başlıkları ise limitleri belirtir: kaç isteğe izin verildiği, kaç tane kaldığı ve sayacın ne zaman sıfırlanacağı. Örneğin X-RateLimit-Remaining kalanı gösterir. Sıfıra yakınsa, 429'u beklemeden önceden temponuzu düşürmek iyi olur.

Limitler Nasıl Çalışır: Token Bucket ve Kayan Pencere

Sunucular isteklerinizi iki popüler yöntemle sayar.

Token bucket (jeton kovası) şöyle çalışır: Sabit hızla damlayan jetonlarla dolu bir kova düşünün. Her istek bir jeton alır. Jeton yoksa istek 429 koduyla reddedilir. Bu şema kısa patlamalara izin verir: Uzun süre sessiz kaldıysanız kova dolar ve bir seferde bir grup istek yapabilirsiniz.

Kayan pencere (sliding window) son belirli bir aralıktaki (örneğin bir dakika) istek sayısını sayar. Bu penceredeki limiti aştığınızda 429 alırsınız. Burada patlamalar daha sert cezalandırılır.

Paralellik de Bir Limittir

Birçok kişi unutur: Limit sadece sıklıkla ilgili değil, aynı anda yapılan bağlantı sayısıyla da ilgilidir. 500 paralel istek açarsanız, sunucu bunu bir saldırı olarak algılayabilir, dakikadaki toplam sayı az olsa bile. Paralellik, sıklık kadar sıkı bir şekilde sınırlanmalıdır.

İpucu: İstemciyi inşa etmeden önce, hedef hizmetin dokümantasyonundan limitlerini öğrenin. Kesin rakamları bilmek sizi tahminlerden ve gereksiz 429'lardan kurtarır.

✅ Kontrol: 429, 403, 407 ve 503 arasındaki farkı, Retry-After'ı biliyor ve sunucunun isteklerinizi nasıl saydığını anlıyorsunuz. Harika, pratiğe geçiyoruz.

Adım 1: Zaman Aşımlarını Doğru Ayarlayın

Aşamanın Amacı: Hiçbir isteğin sonsuza kadar takılıp kalmasını ve bir çalışanı bloke etmesini önlemek.

Zaman Aşımı Olmayan İstemci Neden Tehlikelidir?

Zaman aşımı olmayan bir istemci, gecikmeli bir bombadır. Sunucu yanıt vermeyi keserse, isteğiniz sonsuza kadar bekler. Takılı kalan bir istek bir çalışanı meşgul eder. On takılı istek – ve tüm çalışan havuzunuz dolar, yeni görevler işlenmez, hizmet aslında durur. Zaman aşımı ilk savunma hattınızdır.

Dört Tür Zaman Aşımı

Doğru bir istemci, her şey için tek bir zaman aşımı koymak yerine birden fazla türü ayırt eder.

  1. Connect timeout (bağlantı) – Sunucuyla bağlantı kurmak için ne kadar bekleyeceğiniz. Sunucu ulaşılamazsa, bunu hızlıca öğrenirsiniz.
  2. Read timeout (okuma) – İstek gönderildikten sonra veri için ne kadar bekleyeceğiniz. İsteği alan ama sessiz kalan sunucuya karşı korur.
  3. Write timeout (yazma) – İstek gövdesinin gönderilmesi için ne kadar bekleneceği. Büyük yüklemeler için önemlidir.
  4. Genel timeout (toplam) – Tüm isteğin (tüm aşamalar dahil) tamamlanması için maksimum süre.

Başlangıç Değerleri Ne Olmalı?

Evrensel rakamlar yoktur ancak makul başlangıç değerleri vardır. Bağlantı için 3-5 saniye alın: bağlantı genellikle hızlı kurulur. Okuma için, hizmetin veriyi ne kadar hızlı döndürdüğüne bağlı olarak 10-30 saniye alın. Genel zaman aşımını, en uzun makul isteği kapsayacak şekilde, örneğin 30-60 saniye olarak ayarlayın.

⚠️ Dikkat: Tüm istekler için 300 saniye gibi devasa zaman aşımları asla koymayın. Bu, sorunları maskeler ve takılı işlemler kuyruğu oluşturur. Uzun süre boşuna beklemektense hızlıca başarısız olup tekrar denemek daha iyidir.

Adım Adım Yapılandırma

  1. Hizmetinize yapılan başarılı bir isteğin genellikle ne kadar sürdüğünü belirleyin. Birkaç kez ölçün.
  2. Okuma zaman aşımını, ortalama yanıt süresinin kabaca iki katına ayarlayın.
  3. Bağlantı zaman aşımını 3-5 saniyeye ayarlayın.
  4. Genel zaman aşımını, makul aşamaların toplamı artı küçük bir pay olarak ayarlayın.
  5. Bir test isteği yapın ve takılı kalmadan tamamlandığından emin olun.

İpucu: Hizmetiniz bazen büyük dosyalar, bazen küçük yanıtlar döndürüyorsa, farklı istek türleri için farklı zaman aşımı profilleri oluşturun. Herkese uyan tek bir boyut yoktur.

Beklenen Sonuç: Bilerek yavaş veya ulaşılamaz bir adrese istek yapıldığında, istemciniz belirlenen süre sonunda anlaşılır bir zaman aşımı hatasıyla tamamlanır, sonsuza kadar takılı kalmaz.

✅ Kontrol: Yanıt vermeyen bir adrese (örneğin var olmayan bir port) istek gönderin. İstemci, belirlenen süre civarında bir zaman aşımı hatası döndürmelidir. Daha uzun sürüyorsa zaman aşımı yanlış ayarlanmıştır.

Adım 2: Exponansiyel Backoff ve Jitter ile Tekrarlar Oluşturun

Aşamanın Amacı: İstemciye, kendisine ve sunucuya zarar vermeden istekleri akıllıca tekrarlamayı öğretmek.

Neler Tekrarlanabilir? İdempotentlik

Bir isteği tekrarlamadan önce kendinize sorun: Bunu iki kez yapmak güvenli mi? Bu özelliğe idempotentlik denir. Bir istek idempotent ise, tekrarı aynı sonucu verir ve yan etkilere neden olmaz.

  • GET, HEAD, PUT, DELETE genellikle idempotenttir. Tekrarlamak güvenlidir.
  • POST genellikle idempotent değildir. Tekrar, siparişin ikinci kez oluşturulmasına, ikinci bir ödemeye veya yinelenen kayda yol açabilir.

⚠️ Dikkat: POST isteklerini asla körü körüne tekrarlamayın. İdempotent olmayan bir isteğin tekrarlanması çifte para çekme veya veri yinelemesine neden olabilir. POST tekrarı gerekiyorsa, sunucunun anlayacağı ve işlemi iki kez gerçekleştirmeyeceği bir idempotentlik anahtarı (Idempotency-Key) kullanın.

Kaç Kez Tekrarlanmalı?

Sonsuz tekrarlar kötüdür. Makul bir sınır 3 ila 5 denemedir. Beş denemeden sonra istek geçmediyse, sorun geçici bir arızadan daha ciddidir ve ayrıca günlüğe kaydedilip ele alınmalıdır.

Exponansiyel Backoff Nedir?

Backoff, tekrarlar arasındaki beklemelerdir. Exponansiyel, bekleme süresinin her denemeyle katlanarak arttığı anlamına gelir. Örneğin: ilk bekleme 1 saniye, ikinci 2 saniye, üçüncü 4, dördüncü 8. Formül basittir: temel gecikme, 2 üzeri deneme sayısı ile çarpılır.

Neden böyle? Sunucu aşırı yüklüyse, kısa ve sık tekrarlar onu bitirir. Artan beklemeler sunucuya toparlanması için zaman verir.

Jitter Olmazsa Neden Tekrar Fırtınası Olur?

Bin istemcinin aynı anda 429 aldığını hayal edin. Hepsi tam 1 saniye, sonra tam 2, sonra tam 4 bekler. Ve hepsi aynı anda tekrar dener. Sonuç senkronize bir fırtınadır: Sunucu yine aynı anda bin istek alır ve yine 429 döndürür. Sorun çözülmez, kısır döngüye girer.

Çözüm jitter'dır, yani beklemeye rastgele bir ekleme. Tam 2 saniye yerine bir istemci 1.7, diğeri 2.3, bir başkası 1.9 bekler. Tekrarlar zamana yayılır ve sunucu yumuşak bir şekilde rahatlar.

Retry-After'a Saygı Gösterme

Sunucu Retry-After başlığı gönderdiyse, bu sizin backoff formülünüzden daha önemlidir. Kural basit: hesaplanan beklemelerinizle Retry-After değerinden büyük olanı alın. Asla sunucunun istediğinden daha erken tekrar denemeyin. Bu büyük bir nezaketsizliktir ve yeni 429'lara yol açar.

Tekrar Mantığının Adım Adım Uygulanması

  1. İsteğin idempotent olup olmadığını kontrol edin. Değilse ve idempotentlik anahtarı yoksa tekrarlamayın.
  2. Yanıt kodunu kontrol edin. Yalnızca 429, 503 ve ağ hatalarında (zaman aşımı, bağlantı kopması) tekrarlayın.
  3. Deneme sayacını artırın. Sınırı aştıysa durun ve hatayı döndürün.
  4. Exponansiyel büyüme formülüyle temel beklemeyi hesaplayın.
  5. Beklemeye rastgele bir jitter ekleyin.
  6. Retry-After gelmişse, iki değerden büyük olanı alın.
  7. Hesaplanan süre kadar bekleyin ve isteği tekrarlayın.

İpucu: Maksimum beklemeyi üstten sınırlayın, örneğin 30 veya 60 saniye. Aksi takdirde beşinci denemede backoff çok büyük değerlere ulaşabilir ve kullanıcı çok uzun süre bekler.

Beklenen Sonuç: 429 kodu alındığında istemci bir bekleme yapar, isteği tekrarlar ve tekrarlar arasındaki beklemeler artar ve her seferinde biraz farklılık gösterir.

✅ Kontrol: Test sunucunuzu art arda birkaç kez 429, ardından 200 döndürecek şekilde ayarlayın. İstemciniz son yanıtı başarıyla almalı ve günlüklerde rastgele dağılımlı artan beklemeler görmelisiniz.

Adım 3: Paralelliği Sınırlayın

Aşamanın Amacı: İstemcinin sunucuyu aynı anda gönderilen isteklerle boğmasını önlemek.

Semafor Basitçe Nedir?

Semafor, bir izin sayacıdır. Sınırlı sayıda kancası olan bir vestiyer düşünün. Boş bir kanca varsa paltoyu asarsınız. Tümü doluysa, biri boşalana kadar beklersiniz. Semafor, aynı anda sınırlı sayıda görevi geçirir, geri kalanını kuyrukta tutar.

Görev Kuyruğu

Yürütülmesi gereken tüm istekler bir kuyruğa konur. Çalışanlar, boşaldıkça kuyruktaki görevleri alır. Bu size tempo üzerinde tam kontrol sağlar: en fazla kaç çalışan, o kadar paralel istek.

Ana Bilgisayar Başına Limit

Önemli bir nüans: limit her ana bilgisayar (host) için ayrı tutulmalıdır. Birden çok hizmetle çalışıyorsanız, her şey için tek bir genel limit optimal değildir. Yavaş bir ana bilgisayar, diğerine yapılan istekleri bloke etmemelidir. Her alan adı için ayrı bir limit belirleyin.

Bağlantı Havuzu ve Keep-Alive

Her yeni TCP bağlantısı zaman alır: el sıkışma, güvenli kanal kurulumu. Keep-alive, bir bağlantıyı art arda birden çok istek için yeniden kullanmanızı sağlar. Bu, zaman ve sunucu kaynaklarından tasarruf sağlar. Bağlantı havuzu, açık bağlantıları hazırda tutar. Havuz boyutunu paralellik limitinizle uyumlu olacak şekilde ayarlayın.

⚠️ Dikkat: Bağlantı havuzu boyutunu paralellik limitiyle karıştırmayın. Havuz, limitin biraz üzerinde olabilir, ancak havuz çok büyük, limit küçükse gereksiz yere açık bağlantı tutarsınız. Makul bir dengede tutun.

Kısıtlama Adım Adım

  1. Ana bilgisayar başına güvenli eşzamanlı istek sayısını belirleyin. Küçük başlayın, örneğin 5-10.
  2. Bu sayıda izinle bir semafor oluşturun.
  3. Her istekten önce semafordan izin isteyin.
  4. İstek başarılı veya başarısız tamamlandıktan sonra izni mutlaka serbest bırakın.
  5. Bağlantı havuzunu aynı değer aralığında keep-alive ile ayarlayın.
  6. 429 oranını ve p95'i gözlemleyerek limiti kademeli olarak artırın. 429 yükselmeye başladığında durun.

İpucu: Semafor iznini bir finally bloğunda veya benzerinde serbest bırakın. Aksi takdirde hata durumunda izin geri dönmez, sayaç sızdırır ve zamanla istemci tamamen durur.

Beklenen Sonuç: Kuyruğa ne kadar görev koyarsanız koyun, ana bilgisayara aynı anda yapılan istek sayısı belirlenen limiti aşmaz.

✅ Kontrol: Limit 5 iken kuyruğa 100 görev koyun. Günlüklerde veya bağlantı monitöründe herhangi bir anda en fazla 5 aktif istek görmelisiniz.

Adım 4: 429 Koduna Doğru Tepki Verin

Aşamanın Amacı: Aşırı yük sinyaline doğru tepkiyi oluşturmak ve IP değişikliğinin ne zaman uygun olduğunu anlamak.

429'da Üç Eylem

429 geldiğinde elinizde üç araç var ve bunları birlikte kullanmalısınız.

  1. Yavaşlayın – sadece bir istek için değil, genel istek temposunu düşürün. Bu kilit nokta: 429, tüm temponuzun çok yüksek olduğuna dair bir sinyaldir.
  2. IP değiştirin – eğer IP rotasyonu ile çalışıyorsanız, adres değiştirmek, limit belirli bir adrese bağlıysa yardımcı olabilir. Ancak bu her derde deva değildir.
  3. Görevi erteleyin – isteği bir gecikmeyle kuyruğa geri koyun, böylece limitler düzeldiğinde daha sonra yürütülsün.

⚠️ Dikkat: IP değişikliği nezaketi ortadan kaldırmaz. Limit IP'ye değil de hesap veya anahtara bağlıysa, hiçbir rotasyon yardımcı olmaz – yine 429'a takılırsınız. Rotasyonu kuralları atlatmanın bir yolu haline getirmeyin: hizmetin limitlerine ve Retry-After'a her durumda saygı gösterin.

Yanıt Kodlarına Göre Eylem Matrisi

Kolayca başvurmak için basit bir karar tablosu hazırlayın. İşte her kodda yapılacaklar.

  • 200-299 Başarı – Yanıtı işleyin, kaynakları serbest bırakın, sonraki görevi alın.
  • 429 Too Many Requests – Tempoyu düşürün, Retry-After'a saygı gösterin, backoff ile tekrar deneyin, gerekirse görevi erteleyin veya IP değiştirin.
  • 503 Service Unavailable – Backoff ile tekrar deneyin, Retry-After'a saygı gösterin, ancak IP değiştirmeyin: sorun sunucu tarafında.
  • 403 Forbidden – Körü körüne tekrarlamayın. Yetkilendirmeyi, başlıkları, izinleri kontrol edin. İnceleme için günlüğe kaydedin.
  • 407 Proxy Authentication Required – Proxy kimlik bilgilerini düzeltin. Ayarlar düzelene kadar tekrarlamayın veya rotasyon yapmayın.
  • 400, 404, 422 istemci hataları – Tekrarlamayın. Bu isteğinizdeki bir hatadır, tekrar hiçbir şeyi değiştirmez.
  • 500, 502, 504 sunucu hataları – Backoff ile az sayıda dikkatlice tekrar deneyin.
  • Ağ hataları ve zaman aşımları – İstek idempotentse backoff ile tekrar deneyin.

429 Tepkisi Adım Adım

  1. 429 aldığınızda, temponuzu artırmayı hemen durdurun.
  2. Varsa Retry-After başlığını okuyun.
  3. Beklemeyi backoff ve Retry-After'dan büyük olanı olarak hesaplayın.
  4. Limit muhtemelen IP'ye bağlıysa ve rotasyonunuz varsa, tekrar denemeden önce adresi değiştirin.
  5. Denemeler tükendiyse, görevi büyük bir gecikmeyle kuyruğa geri koyun.
  6. Sunucuya nefes alma şansı vermek için genel paralellik limitini geçici olarak düşürün.

İpucu: Son bir dakikadaki 429 oranını ayrı bir sayaçta tutun. Oran yükseliyorsa, durum kritik hale gelmeden önce otomatik olarak temponuzu düşürün. Buna uyarlanabilir kısıtlama denir.

Beklenen Sonuç: Bir dizi 429 karşısında istemci kademeli olarak tempoyu düşürür, Retry-After'a saygı gösterir ve sonunda fırtına yaratmadan istekleri başarıyla tamamlar.

✅ Kontrol: Test sunucunuzda bir 429 patlaması simüle edin. İstemci aktiviteyi azaltmalı, tekrarları artırmamalıdır. Bekleme sonrası başarılı yanıtların oranı düzelmelidir.

Adım 5: Circuit Breaker ve Kontrollü Bozulma Ekleyin

Aşamanın Amacı: Uzun süreli sorunlarda hem sizi hem sunucuyu koruyan bir sigorta oluşturmak.

Circuit Breaker Nedir?

Circuit breaker, elektrik panelindeki sigorta gibidir. Hatalar üst üste gelirse, devreyi açar: sorunlu hizmete bir süreliğine istek göndermeyi durdurur. Bu, sunucuyu bitirmekten ve istemcinizin kaynaklarını boşa harcamaktan korur.

Sigortanın Üç Durumu

  • Closed (kapalı) – Normal çalışma, istekler geçer. İstemci hataları sayar.
  • Open (açık) – Çok fazla hata, istekler sunucuya gitmeden hemen bloke edilir. Belirli bir süre bu şekilde kalır.
  • Half-open (yarı açık) – Deneme modu. İstemci, hizmetin düzelip düzelmediğini kontrol etmek için birkaç istek geçirir. Düzeldiyse closed'a döner, düzelmediyse tekrar open olur.

Tam Durdurma Yerine Kontrollü Bozulma

Hizmet kullanılamaz durumda olduğunda her şeyi durdurmak gerekmez. Kontrollü bozulma, daha kötü çalışabilme ancak çalışmaya devam edebilme yeteneğidir. Örnekler: taze veri yerine önbellekten veri sunmak, kısaltılmış bir sonuç göstermek, zorunlu olmayan görevleri ertelemek, hata yerine anlaşılır bir yer tutucu döndürmek.

İpucu: Dış hizmet kapalıyken kullanıcıya veya sisteme ne göstereceğinizi her zaman düşünün. Anlamlı bir mesaj içeren yer tutucu, takılıp kalmaktan veya yığın izinden daha iyidir.

Circuit Breaker Adım Adım

  1. Sigortanın açılması için hata eşiğini belirleyin, örneğin son 20 istekten oluşan bir pencerede yüzde 50 başarısızlık.
  2. Devrenin açık kalacağı süreyi belirleyin, örneğin 30 saniye.
  3. Kayan bir pencerede başarıları ve başarısızlıkları sayın.
  4. Eşik aşıldığında sigortayı open durumuna geçirin.
  5. Süre dolduğunda half-open durumuna geçirin ve birkaç deneme isteği geçirin.
  6. Deneme sonuçlarına göre closed veya tekrar open yapın.

⚠️ Dikkat: Circuit breaker ile tekrarları karıştırmayın. Tekrarlar tek bir isteği yeniden dener, sigorta ise tüm istek akışını yönetir. Birlikte güçlüdürler ancak sigortanın normal tekli arızalar nedeniyle çok erken açılmaması için uyumlu bir şekilde yapılandırılmalıdırlar.

Beklenen Sonuç: Uzun süreli hizmet kullanılamazlığında istemci sunucuya istek göndermeyi durdurur, hızlıca bir yer tutucu döndürür ve periyodik olarak düzelmeyi kontrol eder.

✅ Kontrol: Test sunucunuzu kullanılamaz hale getirin. İstemci bir dizi başarısızlıktan sonra istek göndermeyi bırakmalı (open) ve sunucu düzeldikten sonra half-open üzerinden normal çalışmaya dönmelidir.

Sonucu Kontrol Edin: Hangi Metrikleri Saymalısınız?

Dayanıklılık gözle değerlendirilemez. Rakamlar gerekir. İşte istemcinizin daha güvenilir hale gelip gelmediğini gösterecek temel metrikler.

Temel Göstergeler

  • Başarılı yanıt oranı (success rate) – 2xx koduyla tamamlanan isteklerin yüzdesi. Ne kadar yüksekse o kadar iyi. Yük altında bile istikrarlı bir şekilde yüksek olmasını hedefleyin.
  • p95 gecikme – İsteklerin yüzde 95'inin tamamlandığı süre. Bu gösterge ortalamadan daha dürüsttür çünkü çoğunluğun nasıl hissettiğini gösterir, sadece şanslı istekleri değil.
  • 429 oranı – 429 kodu döndüren yanıtların yüzdesi. Yüksekse çok agresif gönderiyorsunuzdur. Hedef, bunu minimuma indirmektir.
  • İstek başına tekrar sayısı – Başarının ne kadar zor elde edildiğini gösterir. Artış sorunlara işaret eder.
  • Circuit breaker açılma sayısı – Sık açılmalar, hizmetin istikrarsızlığına veya çok agresif yapılandırmaya işaret eder.

Hazırlık Kontrol Listesi

  1. Tüm aşamalar için zaman aşımları ayarlanmış, hiçbir istek sonsuza kadar takılı kalmıyor.
  2. Tekrarlar yalnızca idempotent istekler ve güvenli kodlar için çalışıyor.
  3. Backoff exponansiyel olarak artıyor ve jitter içeriyor.
  4. Retry-After her zaman saygı görüyor.
  5. Paralellik her ana bilgisayar için bir semaforla sınırlandırılmış.
  6. Keep-alive ile bağlantı havuzu limitle uyumlu şekilde yapılandırılmış.
  7. 429 tepkisi tempoyu düşürüyor, tekrarları artırmıyor.
  8. Eylem matrisi kodlara göre uygulanmış.
  9. Circuit breaker uzun süreli arızalara karşı koruma sağlıyor.
  10. Metrikler toplanıyor ve analiz için erişilebilir.

İstemcinin Daha Dayanıklı Olduğunu Nasıl Anlarsınız?

Aynı yük altında iyileştirmeler öncesi ve sonrası metrikleri karşılaştırın. Dayanıklı bir istemci yüksek başarı oranı, düşük 429 oranı, istikrarlı p95 ve takılı kalmamış çalışanlar gösterir. Sunucu kaprisli olsa bile, hizmetiniz basamaklı çökmeler olmadan çalışmaya devam eder.

✅ Kontrol: Test uç noktanızda bir yük testi yapın. Yük altında başarı oranı yüksek kalıyorsa ve takılma yoksa tebrikler, istemciniz dayanıklıdır.

Sık Yapılan Hatalar ve Çözümleri

Hemen herkesin takıldığı yaygın tuzakları inceleyelim.

Hata 1: Tekrarlar Yükü Artırır

Sorun: Sunucu aşırı yüklü ve agresif tekrarlarınız onu iyice bitiriyor. Nedeni: Backoff ve tempo düşüşü olmadan yapılan tekrarlar. Çözüm: Jitter ile exponansiyel backoff ekleyin, deneme sayısını sınırlayın, hata arttıkça genel paralelliği azaltın.

Hata 2: İdempotent Olmayan İsteklerin Tekrarlanması

Sorun: Çifte siparişler, tekrarlanan ödemeler, yinelenen kayıtlar. Nedeni: POST isteklerinin körü körüne tekrarlanması. Çözüm: Yalnızca idempotent yöntemleri tekrarlayın. POST için, sunucunun tanıyacağı ve işlemi iki kez yapmayacağı bir idempotentlik anahtarı kullanın.

Hata 3: 429'u Sonsuz IP Değiştirerek Tedavi Etmek

Sorun: IP'yi tekrar tekrar değiştiriyorsunuz ama 429 geçmiyor. Nedeni: Limit IP'ye değil, anahtara veya hesaba bağlı; ya da toplamda çok fazla gönderiyorsunuz. Çözüm: Tempoyu düşürün ve Retry-After'a saygı gösterin. IP rotasyonu sadece bir araçtır, nezaketin yerini tutmaz.

Hata 4: Senkronize Tekrar Fırtınası

Sorun: Tüm istemciler aynı anda tekrar dener, sunucu yine çöker. Nedeni: Jitter olmadan backoff. Çözüm: Her beklemeye rastgele bir bileşen ekleyin.

Hata 5: Takılı Kalan Çalışanlar

Sorun: Hizmet yavaş yavaş görevleri işleyemez hale gelir. Nedeni: Zaman aşımlarının olmaması, isteklerin sonsuza kadar beklemesi. Çözüm: Tüm isteklere bağlantı, okuma ve genel zaman aşımları ayarlayın.

Hata 6: Semafor İzni Sızıntısı

Sorun: Zamanla istemci istek yapmayı durdurur. Nedeni: Hata durumunda semafor izninin serbest bırakılmaması. Çözüm: İzni bir finally bloğunda serbest bırakın, böylece her zaman gerçekleşir.

Hata 7: 407'ye Yanlış Tepki

Sorun: İstemci sürekli tekrarlar ve IP rotasyonu yapar ama 407 alır. Nedeni: 407 kodu proxyden gelir ve proxy yetkilendirme hatası anlamına gelir, hizmet sorunu değil. Çözüm: Proxy kimlik bilgilerini kontrol edin ve düzeltin. Burada tekrarlar işe yaramaz.

Hazır Kod Parçaları

Aşağıda üç yığın için yaklaşım açıklamaları bulunuyor. Kendi projenize uyarlayın.

Python (httpx ile)

Açık zaman aşımlarıyla bir httpx istemcisi oluşturun; Timeout nesnesinde bağlantı ve okuma ayrı ayrı belirtilir. httpx Limits aracılığıyla ana bilgisayar başına maksimum bağlantı sayısını belirleyin. Çağrıyı bir tekrar döngüsüne sarın: 429 ve 503'te Retry-After'ı okuyun, beklemeyi jitter'lı exponansiyel backoff ile Retry-After değerinden büyük olanı olarak hesaplayın, ardından asyncio sleep ile bekleyin. Paralelliği asyncio Semaphore ile sınırlayın ve finally bloğunda serbest bırakın. Yalnızca idempotent yöntemleri tekrarlayın, deneme sayısını beşle sınırlayın.

Python (urllib3 Retry ile)

urllib3 kütüphanesi hazır bir mekanizma sunar. Bir Retry nesnesi oluşturun: total parametresi deneme sayısını, backoff_factor exponansiyel beklemeleri, status_forcelist tekrarlanacak kodları (ör. 429, 500, 502, 503, 504) belirtir. respect_retry_after_header parametresi Retry-After'a saygıyı etkinleştirir. Bu Retry nesnesini PoolManager'a veya HTTPAdapter aracılığıyla requests adaptörüne iletin. Bu, elle döngü yazmadan temel dayanıklılığı elde etmenin en hızlı yoludur.

Node.js

Zaman aşımı için AbortController ile yerleşik fetch'i kullanın: bir controller oluşturun, abort için setTimeout ayarlayın, signal'i fetch'e iletin. Çağrıyı bir tekrar döngüsüne saran bir fonksiyon yazın. response.status'u kontrol edin: 429 ve 503'te response.headers.get ile Retry-After başlığını okuyun, jitter'lı bir bekleme hesaplayın, setTimeout ile bir promise aracılığıyla bekleyin. Paralelliği sınırlamak için promise tabanlı basit bir semafor veya popüler bir sınırlayıcı kütüphane kullanın. Eşzamanlı promise sayısını bir kuyrukla kontrol altında tutun.

Go

Go'da http.Client'i Timeout alanıyla genel zaman aşımı için yapılandırın; Transport'u MaxIdleConnsPerHost ve IdleConnTimeout parametreleriyle havuz ve keep-alive için ayarlayın. Bağlantı zaman aşımı için net.Dialer ile DialContext kullanın. Bir tekrar döngüsü uygulayın: 429 ve 503'te Retry-After başlığını okuyun, exponansiyel büyüme ve rastgele jitter ile time.Duration olarak bekleme hesaplayın, time.Sleep veya context ile select kullanarak bekleyin. Paralelliği tamponlu bir kanal (semafor olarak) ile sınırlayın: istekten önce kanala yazın, defer içinde kanaldan okuyun.

İpucu: Herhangi bir dilde, ayarları (zaman aşımları, deneme sayısı, paralellik limiti) yapılandırmaya çıkarın, sabit kodlamayın. Böylece her hizmet için kodu yeniden yazmadan davranışı ayarlayabilirsiniz.

Ek Özellikler ve Optimizasyon

Temel istemci çalıştığında, onu daha da akıllı hale getirebilirsiniz.

Uyarlanabilir Tempo Kısıtlaması

Sabit bir limit yerine değişken bir limit yapın. X-RateLimit-Remaining başlıklarını okuyun ve kalan azaldığında önceden tempoyu düşürün. Böylece 429'lar ortaya çıkmadan onlardan kaçınırsınız.

Görev Öncelikleri

Tüm istekler eşit değildir. Öncelikli bir kuyruk yapın: önemli görevler önce yürütülür, zorunlu olmayanlar bozulma durumunda ilk ertelenenler olur.

Önbelleğe Alma

İdempotent GET istekleri için kısa ömürlü bir önbellek ekleyin. Bu, sunucu yükünü ve 429 oranınızı hiçbir hile olmadan azaltır.

Gözlemlenebilirlik

Yapılandırılmış günlükler ve metrikler ekleyin. Her tekrarı, her circuit breaker açılışını, her uzun beklemeyi günlüğe kaydedin. Böylece olayları incelerken darboğazı hızla bulursunuz.

İpucu: Basit bir istemciyle başlayın ve gerçek ihtiyaç ortaya çıktıkça gelişmiş özellikler ekleyin. Erken karmaşıklık, yokluğu kadar zararlıdır.

SSS: Sık Sorulan Sorular

Retry-After büyük olsa bile her zaman saygı göstermek gerekli mi?

Evet. Retry-After senaryonuz için çok büyükse, zamanından önce tekrar etmektense görevi ertelemek veya bozulmuş bir yanıt döndürmek daha iyidir. Retry-After'ı görmezden gelmek neredeyse her zaman yeni 429'lara yol açar.

POST istekleri tekrarlanabilir mi?

Sadece dikkatlice. İşlem idempotent değilse, tekrar bir kopya oluşturabilir. Sunucunun sizi çifte yürütmeden koruması için bir idempotentlik anahtarı kullanın.

Başlangıç için kaç eşzamanlı istek alınmalı?

Küçük başlayın, örneğin ana bilgisayar başına 5-10, ve 429 oranı ile p95'i gözlemleyerek artırın. 429 yükselmeye başladığında tavanı bulmuşsunuzdur.

429 ile 503 pratikte nasıl farklıdır?

429 sizin temponuzla ilgilidir: çok sık gönderiyorsunuz. 503 sunucuyla ilgilidir: kendisi aşırı yüklü veya bakımda. 429'da tempoyu düşürmek ve muhtemelen IP değiştirmek faydalıdır. 503'te IP değiştirmenin bir anlamı yok, sadece daha sonra tekrar deneyin.

İstemcim neden bazen 407 alıyor?

407 kodu proxyden gelir ve proxy'de yetkilendirmenin geçmediği anlamına gelir. Proxy kullanıcı adı ve şifresini kontrol edin. IP rotasyonu ve backoff burada işe yaramaz – bu bir yapılandırma hatasıdır.

Kaç tekrar denemesi normal kabul edilir?

Genellikle üç ila beş. Daha fazlası nadiren anlamlıdır: beş denemeden sonra işe yaramadıysa, sorun geçici bir arızadan daha ciddidir.

Backoff zaten artıyorsa neden jitter gerekli?

Jitter olmadan birçok istemci aynı anda tekrar dener ve senkronize bir fırtına yaratır. Rastgele dağılım, tekrarları zamana yayar ve sunucuyu yumuşak bir şekilde rahatlatır.

Circuit breaker ne zaman açılmalı?

Kayan bir penceredeki hata oranı belirlenen eşiği (örneğin yarısını) aştığında. Bu, hem sunucuyu hem de sizi boşa kaynak harcamaktan korur.

IP değiştirmek 429'da işe yarar mı?

Bazen, limit IP'ye bağlıysa. Ancak limit anahtara veya hesaba bağlıysa, IP değiştirmek işe yaramaz. IP değiştirme, tempo düşüşü ve Retry-After'a saygının yerini tutmaz.

Hizmet kapalıyken kullanıcıya ne gösterilmeli?

Anlaşılır bir yer tutucu, önbellekten veri veya kısaltılmış bir sonuç. Bu, ekranda takılıp kalmaktan veya teknik bir hatadan daha iyidir.

Sonuç

Uzun bir yol kat ettiniz. Gelin ne inşa ettiğinizi hatırlayalım. Hiçbir isteğin sonsuza kadar takılı kalmaması için tüm aşamalar için zaman aşımları ayarladınız. Yalnızca güvenli istekleri tekrarlayan ve Retry-After'a saygı gösteren, jitter'lı exponansiyel backoff ile akıllı tekrarlar eklediniz. Bir semaforla paralelliği sınırladınız ve keep-alive ile bağlantı havuzu yapılandırdınız. 429'a doğru tepkiyi oluşturdunuz ve yanıt kodlarına göre bir eylem matrisi hazırladınız. Son olarak, circuit breaker ve kontrollü bozulma eklediniz.

Tüm kılavuzun ana fikri basit. 429 bir hata değil, bir konuşmadır. Sunucu size tempoyu düşürmenizi söyler ve kibar bir istemci dinler. Dayanıklılık saldırganlıktan değil, gerektiğinde yavaşlayabilme yeteneğinden doğar.

Şimdi Ne Yapmalı?

Gerçek bir yük altında metrikleri toplayın ve başarı ile 429 oranlarına bakın. Limitleri kademeli olarak her hizmete göre ayarlayın. X-RateLimit başlıklarına göre uyarlanabilir tempo kısıtlaması ekleyin. İdempotent istekler için önbelleğe almayı uygulayın.

Nereden Devam Edilmeli?

IP adres havuzu ve sağlığı konusunu ayrıca inceleyin – bu, burada bilinçli olarak değinmediğimiz büyük bir komşu alandır. Gözlemlenebilirlik konusuna dalın: izleme, panolar, uyarılar. Ve çalıştığınız hizmetlerin dokümantasyonunu mutlaka okuyun: kesin limitler her zaman tahminlerden daha iyidir.

Harika iş çıkardınız. Artık panik yapmayan, aksine dayanıklı ve kibar davranan bir istemciniz var. Bu, güvenilir entegrasyonların üzerine inşa edildiği temeldir. Projelerinizde başarılar dileriz.