Mario

WFN Üye
Konular
574
Mesajlar
574
Çözüm
0
Ticaret Puanı
0
Üyelik
24 Gün
Konum
Zonguldak
Web Sitesi
Var
Alanı
Google Optimiz.
1/1
Konu sahibi
İstek başarısız olduğunda aynı işlemi sınırsızca tekrarlamak yerine, geçici hataları belirli bir deneme sayısıyla ve bekleme süresini artırarak yeniden deneyin. Python’un standart kütüphanesinde bunu urllib.request ile bir döngü, urllib.error.HTTPError ve urllib.error.URLError istisnalarını ayırarak yapabilirsiniz. Başarısızlığın kalıcı bir HTTP hatası mı, ağ sorunu mu yoksa geçici sunucu yanıtı mı olduğunu kontrol etmek, hangi durumlarda yeniden deneme yapılacağını belirler.

Yeniden deneme mantığı nasıl çalışır?​


Her denemede istek gönderilir. İstek başarılı olursa yanıt işlenir ve döngü sona erer. Geçici olduğu düşünülen bir hata oluşursa program kısa bir süre bekler ve isteği yeniden gönderir. Deneme sayısı dolarsa hata üst seviyeye aktarılır.

Bekleme süresini her denemede artırmak için üstel geri çekilme kullanılır. Örneğin bekleme süresi 1, 2 ve 4 saniye olabilir. Bu yöntem, sorun yaşayan sunucuya arka arkaya çok sayıda istek gönderilmesini önler.

Python’da urlopen() HTTP hatalarında HTTPError, bağlantı veya ağ sorunlarında ise URLError oluşturabilir. HTTPError aynı zamanda HTTP durum kodunu code alanında taşır; bu kod, yeniden deneme kararının temelidir.

Standart kütüphane ile uygulanabilir örnek​


Aşağıdaki örnek, JSON döndüren varsayımsal bir API’ye GET isteği gönderir. 503, 502, 504 ve 429 gibi geçici olabilecek yanıtlar yeniden denenir. İstek zaman aşımına uğrarsa veya sunucuya ulaşılamazsa URLError için de yeniden deneme yapılır.

Python:
import json
import time
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen


def get_json_with_retry(url, max_attempts=4, timeout=10):
    retryable_statuses = {429, 500, 502, 503, 504}

    request = Request(
        url,
        headers={
            "Accept": "application/json",
            "User-Agent": "Python-retry-client/1.0",
        },
        method="GET",
    )

    for attempt in range(1, max_attempts + 1):
        try:
            with urlopen(request, timeout=timeout) as response:
                body = response.read().decode("utf-8")
                return json.loads(body)

        except HTTPError as error:
            if error.code not in retryable_statuses:
                raise

            if attempt == max_attempts:
                raise

            retry_after = error.headers.get("Retry-After")
            try:
                wait_seconds = float(retry_after)
            except (TypeError, ValueError):
                wait_seconds = 2 ** (attempt - 1)

            time.sleep(wait_seconds)

        except URLError:
            if attempt == max_attempts:
                raise

            wait_seconds = 2 ** (attempt - 1)
            time.sleep(wait_seconds)


if __name__ == "__main__":
    api_url = "https://example.com/api/data"

    try:
        result = get_json_with_retry(api_url)
        print(result)
    except HTTPError as error:
        print(f"HTTP hatası: {error.code} - {error.reason}")
    except URLError as error:
        print(f"Ağ hatası: {error.reason}")
    except json.JSONDecodeError:
        print("Sunucu yanıtı geçerli JSON değil.")

Kodu çalıştırmak için Python dosyasına kaydedin ve api_url değerini gerçek API adresiyle değiştirin. API kimlik doğrulaması istiyorsa gerekli başlığı, örneğin Authorization değerini headers sözlüğüne ekleyin. API yanıtı JSON değilse json.loads() satırını yanıtın gerçek biçimine göre değiştirmeniz gerekir.

Başarılı bir yanıt alındığında return çalışır ve sonraki denemeler yapılmaz. Örneğin API iki kez 503 döndürüp üçüncü denemede 200 döndürürse program üçüncü yanıttaki JSON verisini kullanır. Dört denemenin tamamı geçici hatayla sonuçlanırsa son hata yeniden oluşturulur ve dışarıdaki except bloğunda görüntülenir.

Hangi hatalar yeniden denenmeli?​


Her başarısız isteği yeniden denemek doğru değildir. İstemcinin gönderdiği bilgiler hatalıysa aynı isteği tekrarlamak sonucu değiştirmez. Bu nedenle durum kodlarını geçici ve kalıcı hatalar olarak ayırın.
Durum veya hataYeniden deneme kararıSonraki işlem
429 Too Many RequestsGenellikle yeniden denenebilirVarsa Retry-After süresini bekleyin; yoksa artan bekleme kullanın
500, 502, 503, 504Genellikle yeniden denenebilirSınırlı sayıda tekrar deneyin; son denemede hatayı kaydedin
400, 401, 403, 404Genellikle yeniden denenmemeliİstek gövdesini, kimlik bilgilerini, yetkileri veya URL’yi kontrol edin
URLError veya zaman aşımıSınırlı sayıda yeniden denenebilirAğ bağlantısını, DNS’i, proxy’yi ve timeout değerini inceleyin
Bu tablo genel bir başlangıç kuralıdır; bir API’nin belgeleri farklı davranış belirleyebilir. Örneğin bazı servisler 400 yanıtını geçici bir kota veya özel uygulama hatası için kullanabilir. Bu durumda yalnız durum koduna değil, yanıt gövdesindeki hata koduna ve API belgelerine de bakın.

401 yanıtı çoğunlukla kimlik doğrulama bilgilerinin geçersiz veya süresinin dolmuş olduğunu gösterir. Kimlik bilgileri değiştirilmeden yeniden denemek işe yaramaz. 403 yetki eksikliğine, 404 ise yanlış URL’ye veya bulunmayan kaynağa işaret edebilir. Bu yanıtlar alınca beklemek yerine isteğin adresini, erişim izinlerini ve gönderilen parametreleri kontrol edin.

POST ve benzeri işlemlerde dikkat edilmesi gerekenler​


GET istekleri genellikle aynı kaynağı okumak için kullanıldığı için yeniden denemeye daha uygundur. POST, PUT veya DELETE isteğini otomatik olarak tekrarlamak ise sunucuda işlemin iki kez uygulanmasına yol açabilir. Örneğin ödeme oluşturma veya sipariş kaydetme isteği ilk denemede sunucuya ulaşıp yalnızca yanıt istemciye dönmeden bağlantı koptuysa, ikinci deneme ikinci bir kayıt oluşturabilir.

Bu tür işlemleri ancak API idempotency key adı verilen benzersiz işlem anahtarını destekliyorsa veya işlemin tekrarlanmasının güvenli olduğundan eminseniz otomatik olarak yeniden deneyin. Her denemede yeni bir anahtar üretmek yerine aynı mantıksal işlem için aynı anahtarı kullanmak, sunucunun yinelenen isteği ayırt etmesine yardımcı olur.

İstek gövdesi dosya, akış veya tek kullanımlık bir nesne içeriyorsa yeniden denemeden önce gövdenin yeniden üretilebilir olduğundan emin olun. Dosya akışı ilk denemede sona geldiyse aynı nesneyi tekrar göndermek boş veya eksik veri gönderebilir.

Bekleme süresini ve deneme sayısını nasıl seçmelisiniz?​


max_attempts=4 değeri örnektir; her servis için sabit doğru yoktur. Kısa bir otomasyon betiğinde iki veya üç deneme yeterli olabilir. Sunucu görevi daha uzun süre çalışabiliyorsa daha fazla deneme yapılabilir, ancak toplam bekleme süresinin kabul edilebilir sınırlar içinde kalması gerekir.

Üstel geri çekilmede 2 ** (attempt - 1) ifadesi ilk beklemeyi 1, sonraki beklemeleri 2, 4 ve 8 saniye yapar. Çok sayıda istemci aynı anda yeniden deniyorsa bunların aynı saniyede tekrar gönderilmesini önlemek için beklemeye küçük bir rastgelelik payı ekleyebilirsiniz:

Python:
import random

wait_seconds = (2 ** (attempt - 1)) + random.uniform(0, 0.5)
time.sleep(wait_seconds)

Sunucu Retry-After başlığı gönderiyorsa örnekte bu değer öncelikli olarak kullanılır. Bu başlık saniye cinsinden bir sayı veya HTTP tarih biçiminde olabilir. Örnekte sayı biçimi ele alınmıştır; tarih biçimini desteklemeniz gereken bir API’de başlığın tarih olarak ayrıştırılması ayrıca uygulanmalıdır.

Hata kaydını nasıl anlamlandırmalısınız?​


Yalnızca “istek başarısız oldu” mesajı sorunu çözmek için yeterli değildir. Her son denemede en azından URL’nin hassas bilgileri içermeyen bölümünü, HTTP durum kodunu, hata türünü, toplam deneme sayısını ve bekleme sonrasında işlemin başarısız kaldığını kaydedin. API anahtarlarını, parolaları ve kişisel verileri günlüğe yazmayın.

Son denemede HTTPError alıyorsanız sunucunun verdiği durum kodunu ve mümkünse hata gövdesini inceleyin. URLError alıyorsanız error.reason değerini kontrol edin; bu değer DNS çözümleme, bağlantı reddi veya başka bir ağ sorununu gösterebilir. JSON ayrıştırma hatası almanız ise HTTP isteğinin başarısız olduğu anlamına gelmez; sunucu başarılı bir HTTP yanıtı vermiş, ancak beklediğiniz JSON yerine farklı bir içerik döndürmüş olabilir.

Üçüncü taraf API kullanıyorsanız yeniden deneme kararını servis belgelerindeki kota, hız sınırı, kimlik doğrulama ve işlem tekrarı kurallarıyla karşılaştırın. Son deneme de başarısız olunca programın sessizce boş veri döndürmesi yerine hatayı çağıran koda iletmek, otomasyonun yanlış başarı raporlamasını önler.

Sık sorulan sorular​

Her HTTP durum kodunda yeniden deneme yapılır mı?​

Hayır. Geçici sunucu ve ağ sorunlarında sınırlı yeniden deneme yapılabilir. Yanlış URL, eksik yetki veya hatalı istek verisi düzeltilmeden tekrarlanırsa aynı hata yeniden oluşur.

Deneme sayısı dolunca program ne yapmalı?​

Son hatayı çağıran koda aktarmalı veya otomasyon sisteminin anlayacağı bir hata kaydı oluşturmalısınız. Başarısız işlemi başarılıymış gibi boş bir değerle devam ettirmek, asıl sorunu gizler.

POST isteği otomatik olarak yeniden denenebilir mi?​

Yalnızca işlemin tekrarlanması güvenliyse veya API idempotency key desteği sağlıyorsa yeniden deneyin. Aksi durumda aynı siparişin, kaydın veya ödemenin birden fazla kez oluşturulma riski vardır.

Yeniden deneme sunucunun kesin olarak düzeleceğini gösterir mi?​

Hayır. Yeniden deneme yalnızca geçici bir sorunun ortadan kalkma ihtimaline karşı ek şans verir. Tüm denemeler başarısızsa ağ bağlantısını, timeout değerini, kimlik bilgilerini, URL’yi, API kotasını ve sunucunun hata yanıtını ayrı ayrı incelemelisiniz.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic