0Pricing
Go Academy · Lekcja

Wycofywanie i ponawianie

Ponawiaj próby z wycofywaniem

Wycofywanie i ponawianie to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

Dlaczego ponawiać próby

Przejściowe błędy, przekroczenia limitu czasu, zerwane połączenia i krótkotrwałe błędy 503 często ustępują przy drugiej próbie. Ponawianie prób przekształca niestabilną operację w niezawodną, bez angażowania wywołującego ją kodu.

Naiwne ponawianie prób jest niebezpieczne

Natychmiastowe ponawianie prób w ciasnej pętli przeciąża niedziałającą poprawnie usługę i może wywołać lawinę ponowień. Potrzebne są opóźnienia między próbami, a opóźnienia te powinny rosnąć.

Wykładniczy backoff

Wykładniczy backoff podwaja czas oczekiwania po każdym błędzie: 100ms, 200ms, 400ms, 800ms. Daje to usłudze downstream czas na odzyskanie sprawności.

delay := 100 * time.Millisecond
for attempt := 0; attempt < 5; attempt++ {
    // try, on failure:
    time.Sleep(delay)
    delay *= 2
}

Dodawanie jittera

Jeśli wiele klientów stosuje backoff w tym samym rytmie, ponawiają próbę w tej samej chwili, powodując efekt tłumu. Jitter nieznacznie losowo zmienia każde opóźnienie, dzięki czemu ponowienia rozkładają się w czasie.

jitter := time.Duration(rand.Int63n(int64(delay) / 2))
time.Sleep(delay + jitter)

Ograniczanie opóźnienia

Wzrost wykładniczy szybko prowadzi do bardzo dużych wartości. Należy ograniczyć opóźnienie do maksymalnej wartości, aby nie czekać między próbami całymi minutami.

if delay > 2*time.Second {
    delay = 2 * time.Second
}

Ograniczanie liczby prób

Należy zawsze ograniczyć liczbę prób. Po osiągnięciu limitu należy zwrócić ostatni błąd, aby wywołujący kod mógł zdecydować, co zrobić, zamiast ponawiać próbę w nieskończoność.

Ponawianie tylko operacji idempotentnych

Ponawianie prób jest bezpieczne tylko wtedy, gdy operację można wykonać dwukrotnie bez szkody. GET jest idempotentny, natomiast nieidempotentnego żądania POST, które obciąża kartę, nie należy bezrefleksyjnie ponawiać. W razie potrzeby należy użyć kluczy idempotencji.

Kompletne ponawianie z backoffem

Ten program ponawia wywołanie funkcji, która dwukrotnie kończy się błędem, a następnie działa poprawnie, za każdym razem podwajając opóźnienie. Wykorzystuje wyłącznie bibliotekę standardową.

package main

import (
    "errors"
    "fmt"
    "time"
)

func flaky(attempt int) error {
    if attempt < 2 {
        return errors.New("temporary failure")
    }
    return nil
}

func main() {
    delay := 50 * time.Millisecond
    var err error
    for attempt := 0; attempt < 5; attempt++ {
        err = flaky(attempt)
        if err == nil {
            fmt.Println("succeeded on attempt", attempt)
            return
        }
        fmt.Printf("attempt %d failed, waiting %v\n", attempt, delay)
        time.Sleep(delay)
        delay *= 2
    }
    fmt.Println("gave up:", err)
}

Uwzględnianie context

Należy przekazać context do pętli ponawiania prób i podczas oczekiwania użyć select z ctx.Done(). Dzięki temu anulowanie lub przekroczenie limitu czasu przez wywołującego pozwala natychmiast przerwać ponawianie prób.

select {
case <-ctx.Done():
    return ctx.Err()
case <-time.After(delay):
}

Rozróżnianie błędów

Nie każdy błąd można ponowić. Błąd 400 Bad Request będzie występował bez końca. Należy sprawdzić błąd lub kod statusu i ponawiać próby tylko dla przejściowych klas błędów, takich jak przekroczenia limitu czasu, 429 i 5xx.

Circuit breaker

Gdy błędy utrzymują się przez dłuższy czas, circuit breaker przestaje wysyłać żądania na czas schładzania zamiast ponawiać każde wywołanie. Uzupełnia backoff, chroniąc przed wyraźnie niedostępną zależnością.

Szybkie sprawdzenie

Sprawdź swoją wiedzę o backoffie.

Podsumowanie

Poznali Państwo backoff i ponawianie prób:

  • Wykładniczy backoff podwaja opóźnienie po każdym błędzie
  • Jitter zapobiega zsynchronizowanym lawinom ponowień
  • Należy ograniczyć opóźnienie i liczbę prób
  • Próby należy ponawiać tylko dla operacji idempotentnych lub błędów, które można ponowić
  • Należy uwzględniać context, aby umożliwić anulowanie

Często zadawane pytania

Czy lekcja „Wycofywanie i ponawianie” jest bezpłatna?

Tak — pełny tekst „Wycofywanie i ponawianie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wycofywanie i ponawianie”?

Ponawiaj próby z wycofywaniem Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Wycofywanie i ponawianie”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Koncepcja wiadra tokenów
  2. golang.org/x/time/rate
  3. Ograniczanie goroutines
  4. Wycofywanie i ponawianie
← Powrót do Go Academy