Odolná integrace
Jak řešit výpadek externího API
Externí služba jednou spadne. Rozhodující je, zda tím zastavíš i vlastní aplikaci.
Nejdřív stručně
Co se při výpadku děje?
Volání externího API může skončit chybou, dlouho čekat nebo vrátit neúplnou odpověď. Výpadek není výjimka v návrhu. Je to běžný stav, na který se připravíš.
Nastav krátký timeout, rozumně opakuj jen dočasné chyby a při delším výpadku přestaň službu zatěžovat. Uživatel má dostat srozumitelný výsledek.
Připrav si
Co budeš potřebovat
Než přidáš retry, zjisti, které volání opravdu smíš opakovat.
- Seznam míst, kde aplikace volá externí API, a jasnou odpovědnost za každé volání.
- Dohodu s poskytovatelem: limity, chybové kódy, timeouty a stavovou stránku.
- Frontu zpráv pro práci, která nemusí doběhnout hned. Uživatel pak nečeká na cizí API.
- Logy a metriku počtu chyb, délky volání a počtu neúspěšných úloh.
Krok 1
Přidej bezpečnostní síť
Ochrana má tři vrstvy: rychle poznat problém, zkusit rozumnou obnovu a umět fungovat omezeně.
1. Nastav krátké timeouty
- Odděl timeout pro připojení a pro celou odpověď. Hodnoty zvol podle konkrétní funkce, ne podle pocitu.
- Nenech jeden pomalý požadavek blokovat PHP worker nebo odpověď uživateli.
- Zaloguj URL bez tajných údajů, délku, stav a typ chyby.
$client->request('GET', $url, ['timeout' => 5]) Symfony HTTP Client 2. Opakuj jen přechodné chyby
- Pro síťovou chybu, 429 nebo 5xx použij omezený retry. Chyby 400 až 404 obvykle oprav v datech, ne opakováním.
- Čekání mezi pokusy prodlužuj. Přidej malou náhodu, aby více workerů neútočilo ve stejný okamžik.
- Zápisové požadavky opakuj jen tehdy, když má poskytovatel idempotency key nebo vlastní bezpečný mechanismus.
retry: 3; delay: 1000; multiplier: 2 Symfony Messenger: retries and failures 3. Přepni do omezeného režimu
- Po několika selháních circuit breaker otevři: další volání krátce neprováděj a vrať známou, bezpečnou odpověď.
- Fallback může být poslední známá hodnota, možnost akci dokončit později nebo jasná informace uživateli.
- Práci, která musí doběhnout, ulož do fronty. Po obnově služby ji zpracuješ kontrolovaně.
external_api_state = "open" RFC 9110: HTTP status codes Krok 2
Natrénuj výpadek
Důvěru dá až test, ne konfigurace v souboru.
-
Vrať timeout
V testovacím prostředí nasměruj klienta na pomalou nebo neexistující adresu. Odpověď vlastní aplikace musí skončit v plánovaném čase.
-
Vrať 503 a 429
Ověř, že proběhne jen omezený počet opakování a interval se prodlužuje.
-
Zkontroluj návrat do normálu
Po obnovení služby nech jeden kontrolní požadavek projít. Fronta se má postupně zpracovat, ne vyprázdnit naráz.
php bin/console messenger:failed:show
Když to zlobí
Nejčastější chyby
Aplikace při výpadku zamrzne
Chybí timeout nebo je příliš dlouhý. Nastav limit pro připojení i celou odpověď.
Retry výpadek ještě zhorší
Sniž počet pokusů a přidej prodlužující čekání. Respektuj také rate limiting poskytovatele.
Objednávka vznikne dvakrát
Zápisový požadavek se opakoval bez ochrany. Použij unikátní klíč a idempotenci.
Otevřený circuit breaker už se nezavře
Přidej krátký cooldown a jeden kontrolní požadavek. Stav breakeru měř a zobraz v monitoringu.
Hotovo
Výpadek už není katastrofa.
Aplikace má timeout, omezené opakování a bezpečný omezený režim. Teď už jen sleduj metriky a pravidla uprav podle provozu.