Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Ein Statuscode von 500 bis 599 bedeutet, dass der Server eine gültige Anforderung nicht erfüllen konnte. Ihre Anfrage ist nicht das Problem, also kann es funktionieren, sie erneut zu senden. Ob Sie es erneut senden sollten, hängt vom Statuscode und davon ab, was die Anfrage bewirkt. Die Definitionen finden Sie unter RFC 9110, Abschnitt 15.6.
Was jeder Statuscode bedeutet
| Statuscode | Was dies bedeutet | Erneut versuchen? |
|---|---|---|
500 Internal Server Error |
Der Server ist auf einen unerwarteten Zustand gestoßen. | Dies hängt von der API ab. Einige APIs, z. B. die Claude-API, teilen Ihnen mit, eine 500 mit exponentiellem Backoff erneut zu versuchen. Lesen Sie die API-Dokumentation. |
502 Bad Gateway |
Ein Gateway oder Proxy hat eine ungültige Antwort vom Server dahinter erhalten. | Ja, wenn die Anforderung sicher wiederholt werden kann |
503 Service Unavailable |
Der Server ist vorübergehend überlastet oder wegen Wartungsarbeiten nicht verfügbar, und er sollte sich nach einiger Zeit wieder erholen. Der Server kann einen Retry-After Header senden. |
Ja, nach dem Retry-After-Zeitpunkt, wenn der Server einen gesendet hat |
504 Gateway Timeout |
Ein Gateway oder Proxy hat nicht rechtzeitig vom dahinterliegenden Server eine Antwort erhalten. | Ja, wenn die Anfrage sicher wiederholt werden kann. Das Gateway hat das Warten aufgegeben, sodass Sie nicht wissen, ob der Server die Arbeit ausgeführt hat. |
Welche Anfragen sicher erneut versucht werden können
RFC 9110 bezeichnet eine Methode als idempotent, wenn das mehrmalige Senden derselben Anfrage die gleiche Wirkung hat wie das einmalige Senden.
GET, HEAD, OPTIONS, TRACE, PUT und DELETE sind idempotent.
POST und PATCH sind nicht. Laut RFC sollte ein Client eine Anforderung bei einer Anfrage mit einer nicht-idempotenten Methode nicht automatisch wiederholen, es sei denn, er weiß, dass die Anforderung trotzdem idempotent ist, oder er kann feststellen, dass der Server die ursprüngliche Anforderung nie angewendet hat. Ausführliche Informationen finden Sie unter Idempotent-Methoden.
Ein Wiederholungsversuch POST nach 502 oder 504 kann eine zweite Bestellung erstellen oder eine zweite E-Mail senden. Einige Wiederholungsbibliotheken wiederholen standardmäßig jede Methode. Beispielsweise wiederholt der .NET-Standardresilienzhandler den Vorgang POST, es sei denn, Sie rufen options.Retry.DisableForUnsafeHttpMethods() auf. Ausführliche Informationen finden Sie unter Resiliente HTTP-Apps erstellen.
Retry-After bei einem 503-Fehler
Ein 503 kann einen Retry-After Header enthalten. Der Wert ist entweder eine Anzahl von Sekunden, z. B. 120, oder ein HTTP-Datum, z. B. Fri, 31 Dec 1999 23:59:59 GMT. Ihr Code muss beide behandeln. Weitere Informationen finden Sie unter Retry-After.
Das Aufrufen einer API beenden, die immer wieder fehlschlägt
Wiederholungsversuche helfen bei kurzzeitigen Fehlschlägen. Wenn eine API für Minuten nicht verfügbar ist, erhöht das erneute Wiederholen jeder Anforderung die Last auf einem Server, der bereits Probleme hat, und Ihre Benutzer warten, bis jeder erneute Versuch fehlschlägt. Ein Circuit Breaker verfolgt Fehler, und wenn zu viele Fehler auftreten, setzt er API-Aufrufe für eine Weile aus und schlägt sofort fehl. Danach können einige Anfragen durchlaufen werden, um zu überprüfen, ob die API wiederhergestellt wurde. Weitere Informationen finden Sie unter Muster „Circuit Breaker“. Der .NET-Standardresilienzhandler enthält einen Trennschalter, der sich 5 Sekunden lang öffnet, wenn mindestens 10 % der Anforderungen in einem 30-Sekunden-Fenster mit mindestens 100 Anforderungen fehlschlagen.
Behandeln von 5xx-Fehlern
- Wiederholen Sie Anfragen mit den Antworten 502, 503 und 504 nur bei idempotenten Anfragen.
POSTundPATCHnur dann wiederholen, wenn die API-Dokumentation beschreibt, wie sie sicher wiederholt werden können. - Warten Sie, bevor Sie es erneut versuchen. Verwenden Sie
Retry-After, wenn der Server es sendet. Verwenden Sie andernfalls exponentielle Backoffs mit zufälligem Jitter, und hören Sie nach einigen Versuchen auf. - Lesen Sie die Dokumentation der API für die Antwort 500. Versuchen Sie es nur dann erneut, wenn die API angibt, dass dies sicher ist.
- Beenden Sie das Aufrufen einer API, die immer wieder fehlschlägt. Verwenden Sie einen Trennschalter, damit Ihre App schnell fehlschlägt, während die API wiederhergestellt wird.
- Teilen Sie dem Benutzer mit, was passiert ist. Zeigen Sie „Es gibt Probleme mit dem Dienst. Versuchen Sie es später erneut.“ anstelle eines generischen Fehlers oder einer Stacktrace an.
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));
}
}
So testen Sie, dass Ihre App 5xx-Fehler behandelt
Bei der Entwicklung wird selten ein 5xx-Fehler ausgegeben, und das gezieltes Fehlschlagen einer API ist nicht möglich. Die Art und Weise, wie Sie testen, entscheidet, ob Sie die Fehler finden, bevor Ihre Benutzer dies tun.
| Approach | Was Sie finden | Was Ihnen fehlt |
|---|---|---|
| Auf die Produktion warten | Tatsächliche Ausfälle | Alles, bis ein Benutzer darauf klickt |
| Die API in Ihren Tests simulieren oder Ihren Codierungs-Agent das Modell schreiben lassen | Ob Ihre Fehlerverzweigung ausgeführt wird | Der tatsächliche HTTP-Client und die Wiederholungsbibliothek und die Häufigkeit der tatsächlichen erneuten Versuche. Ihre App benötigt außerdem einen reinen Testschalter, um das Modell zu erreichen. |
| Rufen Sie die echte API auf, und warten Sie, bis die API fehlschlägt. | Tatsächliches Verhalten | Sie können die API nicht absichtlich Fehlschlagen lassen |
| Den tatsächlichen Datenverkehr Ihrer App abfangen und 5xx-Fehler mit einer von Ihnen ausgewählten Rate zurückgeben | Der echte HTTP-Client, die Retry-Bibliothek und der Circuit Breaker | An Ihrer App ändert sich nichts, daher wird Ihr Code nicht isoliert getestet. Verwenden Sie dafür Ihre Komponententests. |
Probieren Sie sie in Ihrer App aus
Dev Proxy fängt die Anforderungen Ihrer App ab und lässt einen Teil davon mit den von Ihnen definierten Fehlern mithilfe von GenericRandomErrorPlugin fehlschlagen. Ihre App ruft weiterhin die echte URL auf. Fügen Sie das Plug-In zu Ihrer Konfigurationsdatei hinzu, und verweisen Sie mit seinem errorsFile auf eine Datei mit den 5xx-Fehlern. In diesem Beispiel wird https://api.contoso.com verwendet. Ersetzen Sie sie durch die URL der API, die Ihre App aufruft.
Datei: server-errors.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v4.0.0/genericrandomerrorplugin.errorsfile.schema.json",
"errors": [
{
"request": {
"url": "https://api.contoso.com/*"
},
"responses": [
{ "statusCode": 500 },
{ "statusCode": 502 },
{
"statusCode": 503,
"headers": [
{ "name": "Retry-After", "value": "@dynamic=10" }
]
},
{ "statusCode": 504 }
]
}
]
}
Standardmäßig schlägt das Plug-In bei 50 % der Anfragen fehl. Überprüfen Sie in der Dev Proxy-Ausgabe, dass Ihre App GET-Anfragen wiederholt und jede POST nur einmal sendet. Der @dynamic=10 Wert setzt Retry-After auf 10 Sekunden fest. Damit Dev Proxy meldet, wenn Ihre App die API erneut aufruft, bevor diese Zeit abgelaufen ist, fügen Sie den RetryAfterPlugin vor dem GenericRandomErrorPlugin in der Konfigurationsdatei hinzu. Starten Sie dann Dev Proxy mit --failure-rate 100, um zu sehen, was Ihre App tut, wenn die API weiterhin fehlschlägt. Weitere Informationen finden Sie unter Fehlerrate bei Änderungsanfragen. Informationen zum Installieren von Dev Proxy finden Sie unter Einrichten von Dev Proxy.