Cel nauki: wybrać właściciela ponowień (retry) i ustalić wspólny budżet prób, zamiast nieświadomie mnożyć ruch do przeciążonej usługi.
Scenariusz: dziewięć wywołań zamiast jednego
To fikcyjny przykład edukacyjny, nie opis incydentu produkcyjnego. API wywołuje usługę pośrednią, która odczytuje katalog. Każda z dwóch warstw dopuszcza maksymalnie trzy próby, licząc pierwsze wywołanie. Jeżeli katalog stale odpowiada błędem, jedna operacja użytkownika może wywołać aż dziewięć prób katalogu (3 × 3). Dodatkowy ruch trafia do zależności właśnie wtedy, gdy ma ona najmniej zasobów.
Trzy warianty decyzji
- A — retry w każdej warstwie. Lokalnie proste, globalnie grozi amplifikacją prób i dłuższym ogonem opóźnień.
- B — jeden właściciel retry. Adapter katalogu odpowiada za ponawianie bezpiecznych odczytów, a warstwy nadrzędne przekazują wspólny termin zakończenia (deadline) i nie ponawiają całego łańcucha.
- C — bez retry. Właściwe, gdy powtórzenie operacji może spowodować nieodwracalny skutek uboczny albo nie można ustalić wyniku poprzedniej próby.
Decyzja warunkowa
Wybieramy B dla odczytów, ale tylko po potwierdzeniu zachowania SDK, klienta HTTP, gatewaya i pośredników. Limit prób jest liczony na operację biznesową, nie na każdą warstwę oddzielnie. Backoff z losowym rozproszeniem (jitter) ogranicza synchronizację ponowień; osobny limit współbieżności chroni katalog przed lawiną oczekujących żądań. Gdy wspólny deadline upłynął, nie wykonujemy kolejnej próby. Dla zapisów wymagamy idempotency key albo wiarygodnego mechanizmu sprawdzenia wyniku; bez tego automatyczne ponowienie jest wyłączone.
Jak udowodnić, że projekt działa?
- Rozrysuj rzeczywistą ścieżkę API → usługa pośrednia → katalog i spisz retry w każdym SDK oraz gatewayu.
- W testach wymuś HTTP 429 i 503, osobno z nagłówkiem Retry-After i bez niego. Nagłówek jest wskazówką dotyczącą czasu oczekiwania, a nie nakazem ponawiania poza deadline.
- Zmierz liczbę wywołań katalogu na jedną operację, p95/p99 opóźnienia, liczbę żądań współbieżnych i czas powrotu po ustąpieniu błędu.
- Potwierdź, że próby kończą się po osiągnięciu budżetu oraz że zapis nie jest powtarzany bez bezpiecznego kontraktu.
Pytanie do architekta: jeśli gateway i SDK wykonują retry niezależnie, która warstwa ma prawo ponowić operację i kto odpowiada za łączny koszt prób?
Źródła i dalsza lektura
- Amazon Builders’ Library — Timeouts, retries, and backoff with jitter
- RFC 9110, §10.2.3 — Retry-After
- RFC 6585, §4 — 429 Too Many Requests
Powiązane zagadnienia: idempotencja i sprawdzanie wyniku, bulkhead oraz budżet błędów SLO.
Porozmawiajmy o tym artykule
Podziel się uwagą lub zanonimizowanym przykładem. Komentarze sprawdza AI przed publikacją. Niejednoznaczne przypadki trafiają do moderatora.