Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Stavový kód od 500 do 599 znamená, že se serveru nepodařilo splnit požadavek, který vypadal jako platný. Problém není ve vašem požadavku, takže jeho opětovné odeslání může fungovat. To, jestli byste ho měli poslat znovu, závisí na stavovém kódu a na tom, co požadavek dělá. Definice naleznete v dokumentu RFC 9110, oddílu 15.6.
Význam jednotlivých stavových kódů
| Stavový kód | Co to znamená | Zkuste to znovu? |
|---|---|---|
500 Internal Server Error |
Server narazil na stav, který neočekával. | Závisí na rozhraní API. Některá rozhraní API, jako je Claude API, vám doporučují opakovat požadavek při chybě 500 s exponenciálně se prodlužující prodlevou. Projděte si dokumentaci k rozhraní API. |
502 Bad Gateway |
Brána nebo proxy server získaly neplatnou odpověď z navazujícího serveru | Ano, pokud je požadavek bezpečný k opakování. |
503 Service Unavailable |
Server je dočasně přetížen nebo mimo provoz a po nějaké době by se měl obnovit. Server může odeslat hlavičku Retry-After . |
Ano, po uplynutí doby Retry-After, pokud server nějaký odeslal |
504 Gateway Timeout |
Brána nebo proxy server nedostaly včas odpověď od serveru, který je za ní | Ano, pokud je požadavek bezpečný k opakování. Brána se vzdala čekání, takže nevíte, jestli server provedl požadovanou operaci. |
Které požadavky lze bezpečně zkusit znovu
RFC 9110 označuje metodu za idempotentní, když má odeslání stejného požadavku několikrát stejný účinek jako jeho odeslání jednou.
GET, HEAD, OPTIONS, TRACEPUTa DELETE jsou idempotentní.
POST a PATCH nejsou. Podle RFC by klient neměl automaticky opakovat požadavek s neidempotentní metodou, pokud neví, že požadavek je stejně idempotentní, nebo může zjistit, že server původní požadavek nikdy nezpracoval. Podrobnosti najdete v tématu Idempotentní metody.
POST Opakovaný požadavek po chybě 502 nebo 504 může vytvořit druhou objednávku nebo odeslat druhý e-mail. Některé knihovny pro opakování ve výchozím nastavení opakují všechny metody. Například standardní obslužná rutina odolnosti .NET opakovaně provede POST, pokud nevoláte options.Retry.DisableForUnsafeHttpMethods(). Podrobnosti najdete v článku Vytvoření odolných aplikací HTTP.
Retry-After na 503
A 503 může obsahovat hlavičku Retry-After. Jeho hodnota je buď číselná hodnota v sekundách, například 120, nebo datum HTTP, například Fri, 31 Dec 1999 23:59:59 GMT. Váš kód musí zpracovat obojí. Podrobnosti najdete v tématu Retry-After.
Přestaňte volat rozhraní API, které stále selhává
Opakované pokusy pomáhají s krátkodobými chybami. Když je rozhraní API po dobu několika minut nedostupné, opakování každého požadavku přidává zátěž serveru, který už má potíže, a vaši uživatelé čekají, až každý opakovaný pokus selže. Circuit breaker sleduje chyby a pokud je jich příliš mnoho, přestane na chvíli volat rozhraní API a okamžitě skončí chybou. Po uplynutí této doby propustí několik požadavků, aby ověřilo, zda se rozhraní API obnovilo. Další informace naleznete v tématu vzor Circuit Breaker. Standardní obslužná rutina odolnosti v .NET zahrnuje jistič, který se otevře na 5 sekund, když v 30sekundovém intervalu selže alespoň 10 % požadavků při nejméně 100 požadavcích.
Zpracování chyb 5xx
- Opakujte požadavky pouze při chybách 502, 503 a 504 pro idempotentní požadavky.
PATCHOpakujtePOSTakci pouze v případě, že rozhraní API dokumentuje způsob, jak je bezpečně opakovat. - Počkejte, než to zkusíte znovu. Použijte
Retry-After, když jej server odešle. V opačném případě použijte exponenciální prodlevu s náhodným zpožděním a po několika pokusech zastavte. - Přečtěte si dokumentaci k rozhraní API pro verzi 500. Zkuste to znovu jenom v případě, že rozhraní API říká, že je bezpečné.
- Přestaňte volat rozhraní API, které selhává. Použijte circuit breaker, aby vaše aplikace selhala rychle, zatímco se rozhraní API zotavuje.
- Řekněte uživateli, co se stalo. Zobrazte "služba má problémy, zkuste to znovu později" místo obecné chyby nebo trasování zásobníku.
const RETRYABLE_STATUS = new Set([502, 503, 504]);
const IDEMPOTENT_METHODS = new Set(["GET", "HEAD", "OPTIONS", "TRACE", "PUT", "DELETE"]);
function retryAfterMs(response) {
const value = response.headers.get("retry-after");
if (!value) return null;
const seconds = Number(value);
if (Number.isFinite(seconds)) return seconds * 1000;
const date = Date.parse(value);
return Number.isNaN(date) ? null : Math.max(0, date - Date.now());
}
export async function fetchWithRetry(url, options = {}, maxRetries = 3) {
const method = (options.method ?? "GET").toUpperCase();
const canRetry = IDEMPOTENT_METHODS.has(method);
for (let attempt = 0; ; attempt++) {
const response = await fetch(url, options);
if (!RETRYABLE_STATUS.has(response.status) || !canRetry || attempt === maxRetries) {
return response;
}
await response.body?.cancel();
const backoff = 2 ** attempt * 1000 + Math.random() * 1000;
const wait = retryAfterMs(response) ?? backoff;
await new Promise((resolve) => setTimeout(resolve, wait));
}
}
Jak otestovat, že aplikace zpracovává chyby 5xx
Při vývoji zřídka vidíte 5xx a nemůžete přimět rozhraní API, aby na požádání selhalo. Způsob, jakým testujete, určuje, zda chyby zjistíte dříve, než je najdou vaši uživatelé.
| Approach | Co najdete | Co vám chybí |
|---|---|---|
| Počkejte na produkční prostředí | Skutečné výpadky | Všechno, dokud na to uživatel neklikne |
| Mockujte API v testech nebo nechte svého programovacího agenta napsat mock | Jestli se spouští vaše chybová větev | Váš skutečný klient HTTP a knihovna pro opakování pokusů a kolikrát skutečně provede opakování. Vaše aplikace také potřebuje testovací přepínač pro přístup k mocku. |
| Zavolejte skutečné rozhraní API a počkejte, až selže | Skutečné chování | Nemůžete přimět rozhraní API selhat na požádání |
| Zachyťte skutečný provoz vaší aplikace a vracejte chyby 5xx v míře, kterou zvolíte | Váš skutečný klient HTTP, knihovna pro opakování požadavků a circuit breaker | Ve vaší aplikaci se nic nemění, takže netestuje váš kód izolovaně. Na to si nechte jednotkové testy. |
Vyzkoušejte si ji ve své aplikaci
Dev Proxy zachytí požadavky vaší aplikace a u části z nich vyvolá selhání s chybami, které definujete, pomocí modulu GenericRandomErrorPlugin. Vaše aplikace pořád volá skutečnou adresu URL. Přidejte modul plug-in do konfiguračního souboru a nasměrujte jeho errorsFile na soubor s chybami 5xx. Tento příklad používá https://api.contoso.com. Nahraďte ho adresou URL rozhraní API, které vaše aplikace volá.
Soubor: server-errors.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.errorsfile.schema.json",
"errors": [
{
"request": {
"url": "https://api.contoso.com/*"
},
"responses": [
{ "statusCode": 500 },
{ "statusCode": 502 },
{
"statusCode": 503,
"headers": [
{ "name": "Retry-After", "value": "10" }
]
},
{ "statusCode": 504 }
]
}
]
}
Ve výchozím nastavení modul plug-in selže u 50 % požadavků. Ve výstupu Dev Proxy zkontrolujte, že vaše aplikace opakuje požadavky GET a odesílá každý POST jenom jednou. Dev Proxy nekontroluje, jestli vaše aplikace při odpovědi 503 čeká na Retry-After, takže porovnejte časy požadavků sami. Potom spusťte Dev Proxy pomocí --failure-rate 100 a zjistěte, co vaše aplikace dělá, když volání API opakovaně selhává. Další informace najdete v tématu Četnost selhání žádostí o změnu. Pokud chcete nainstalovat Dev Proxy, přečtěte si téma Nastavení Dev Proxy.