almessadi.
Zur Übersicht

Wiederholungen benötigen Backoff, Jitter und ein klares Budget_

Wiederholungen verbessern die Resilienz nur, wenn sie die Last verteilen und zur richtigen Zeit stoppen. Ohne Backoff und Jitter können sie einen transienten Fehler in einen breiteren Ausfall verwandeln.

Veröffentlicht28. September 2024
Lesezeit7 min read

Wiederholungen sind eines der einfachsten Resilienzmerkmale, die leicht falsch implementiert werden können, da sie auf kleinerer Skala harmlos erscheinen.

Ein einzelner Dienst, der eine fehlgeschlagene Anfrage wiederholt, ist kein Problem. Zehntausend Instanzen, die nach demselben Zeitplan wiederholen, oft schon.

Hier verwandelt sich die Wiederholungslogik von einem Wiederherstellungsmechanismus in einen Lastverstärker.

Das naive Muster

Das ist häufig und gefährlich:

for (let attempt = 0; attempt < 3; attempt += 1) {
  try {
    return await callPaymentApi();
  } catch (error) {
    await sleep(1000);
  }
}

Alle Aufrufer scheitern gleichzeitig. Alle Aufrufer schlafen dieselbe Zeit. Alle Aufrufer wachen gleichzeitig auf und attackieren die Abhängigkeit erneut.

Was bessere Wiederholungslogik umfasst

Gutes Wiederholungsverhalten kombiniert normalerweise:

  • exponentiellen Backoff
  • Jitter
  • ein maximales Wiederholungsbudget

Zum Beispiel:

function backoffMs(attempt: number) {
  const base = 250 * 2 ** attempt;
  const jitter = Math.random() * 0.3 * base;
  return Math.min(base + jitter, 5000);
}

Der Punkt ist nicht mathematische Eleganz. Der Punkt ist, Tausende von Clients daran zu hindern, im Gleichschritt zu wiederholen.

Der Kompromiss

Wiederholungen sind nur sinnvoll für Fehler, die wahrscheinlich transient sind. Sie sind normalerweise falsch für:

  • Validierungsfehler
  • permanente Autorisierungsfehler
  • Anfragen, die ohne Idempotenz nicht sicher wiederholt werden dürfen

Deshalb gehören die Wiederholungsrichtlinie und die Idempotenzrichtlinie zusammen.

Weitere Lektüre