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
- Koncepcja wiadra tokenów
- golang.org/x/time/rate
- Ograniczanie goroutines
- Wycofywanie i ponawianie