Wiederholen Sie asynchrone Funktionen

In diesem Dokument wird beschrieben, wie Sie asynchrone (Nicht-HTTPS-)Hintergrundfunktionen anfordern können, es bei einem Fehler erneut zu versuchen.

Semantik des Wiederholungsversuchs

Cloud Functions garantiert die mindestens einmalige Ausführung einer ereignisgesteuerten Funktion für jedes von einer Ereignisquelle ausgegebene Ereignis. Wenn ein Funktionsaufruf mit einem Fehler endet, wird die Funktion standardmäßig nicht erneut aufgerufen und das Ereignis verworfen. Wenn Sie Wiederholungen für eine ereignisgesteuerte Funktion aktivieren, wiederholt Cloud Functions einen fehlgeschlagenen Funktionsaufruf, bis er erfolgreich abgeschlossen wird oder das Wiederholungsfenster abläuft.

Für Funktionen der 2. Generation läuft dieses Wiederholungsfenster nach 24 Stunden ab. Für Funktionen der 1. Generation läuft es nach 7 Tagen ab. Cloud Functions wiederholt neu erstellte ereignisgesteuerte Funktionen mithilfe einer exponentiellen Backoff-Strategie mit einem zunehmenden Backoff von 10 bis 600 Sekunden. Diese Richtlinie wird auf neue Funktionen angewendet, wenn Sie sie zum ersten Mal bereitstellen. Es wird nicht rückwirkend auf vorhandene Funktionen angewendet, die erstmals bereitgestellt wurden, bevor die in diesem Versionshinweis beschriebenen Änderungen wirksam wurden, selbst wenn Sie die Funktionen erneut bereitstellen.

Wenn Wiederholungsversuche für eine Funktion nicht aktiviert sind (was die Standardeinstellung ist), meldet die Funktion immer, dass sie erfolgreich ausgeführt wurde, und in ihren Protokollen werden möglicherweise 200 OK Antwortcodes angezeigt. Dies geschieht auch dann, wenn bei der Funktion ein Fehler aufgetreten ist. Um deutlich zu machen, wann bei Ihrer Funktion ein Fehler auftritt, stellen Sie sicher, dass Fehler entsprechend gemeldet werden .

Warum ereignisgesteuerte Funktionen nicht abgeschlossen werden können

In seltenen Fällen kann es vorkommen, dass eine Funktion aufgrund eines internen Fehlers vorzeitig beendet wird und die Funktion standardmäßig möglicherweise automatisch erneut ausgeführt wird oder nicht.

Typischer ist, dass eine ereignisgesteuerte Funktion aufgrund von Fehlern im Funktionscode selbst nicht erfolgreich abgeschlossen werden kann. Dies könnte folgende Gründe haben:

  • Die Funktion enthält einen Fehler und die Laufzeit löst eine Ausnahme aus.
  • Die Funktion kann einen Dienstendpunkt nicht erreichen oder es tritt beim Versuch eine Zeitüberschreitung auf.
  • Die Funktion löst absichtlich eine Ausnahme aus (z. B. wenn die Validierung eines Parameters fehlschlägt).
  • Eine Node.js-Funktion gibt ein abgelehntes Versprechen zurück oder übergibt einen Wert ungleich null an einen Rückruf.

In jedem der oben genannten Fälle stoppt die Funktion standardmäßig die Ausführung und das Ereignis wird verworfen. Um die Funktion erneut auszuführen, wenn ein Fehler auftritt, können Sie die standardmäßige Wiederholungsrichtlinie ändern, indem Sie die Eigenschaft „Bei Fehler wiederholen“ festlegen . Dies führt dazu, dass das Ereignis wiederholt wiederholt wird, bis die Funktion erfolgreich abgeschlossen wird oder das Wiederholungszeitlimit abläuft.

Aktivieren oder deaktivieren Sie Wiederholungsversuche

Konfigurieren Sie Wiederholungen über die GCP Console

Wenn Sie eine neue Funktion erstellen:

  1. Wählen Sie im Bildschirm „Funktion erstellen“ die Option „Trigger hinzufügen “ und dann den Ereignistyp aus, der als Auslöser für Ihre Funktion dienen soll.
  2. Aktivieren Sie im Eventarc-Triggerbereich das Kontrollkästchen Bei Fehler wiederholen , um Wiederholungen zu aktivieren.

Wenn Sie eine vorhandene Funktion aktualisieren:

  1. Klicken Sie auf der Seite „Cloud Functions-Übersicht“ auf den Namen der Funktion, die Sie aktualisieren, um den Bildschirm „Funktionsdetails“ zu öffnen. Wählen Sie dann „Bearbeiten“ in der Menüleiste aus, um die HTTPS- und Eventarc- Triggerbereiche anzuzeigen.
  2. Klicken Sie im Eventarc-Trigger- Bereich auf das , um die Einstellungen Ihres Triggers zu bearbeiten.
  3. Aktivieren oder deaktivieren Sie im Eventarc-Triggerbereich das Kontrollkästchen Bei Fehler wiederholen, um Wiederholungen zu aktivieren oder zu deaktivieren.

Konfigurieren Sie Wiederholungen über Ihren Funktionscode

Mit Cloud Functions for Firebase können Sie Wiederholungsversuche im Code für eine Funktion aktivieren. Um dies für eine Hintergrundfunktion wie functions.foo.onBar(myHandler); zu tun. , verwenden Sie runWith und konfigurieren Sie eine Fehlerrichtlinie:

functions.runWith({failurePolicy: true}).foo.onBar(myHandler);

Wenn Sie wie gezeigt auf true setzen, wird eine Funktion so konfiguriert, dass sie es bei einem Fehler erneut versucht.

Empfohlene Vorgehensweise

In diesem Abschnitt werden Best Practices für die Verwendung von Wiederholungsversuchen beschrieben.

Verwenden Sie Wiederholungsversuche, um vorübergehende Fehler zu behandeln

Da Ihre Funktion bis zur erfolgreichen Ausführung kontinuierlich wiederholt wird, sollten dauerhafte Fehler wie Bugs durch Tests aus Ihrem Code beseitigt werden, bevor Wiederholungsversuche aktiviert werden. Wiederholungsversuche eignen sich am besten zur Bewältigung intermittierender/vorübergehender Fehler, bei denen eine hohe Wahrscheinlichkeit besteht, dass sie bei Wiederholungsversuchen behoben werden, z. B. ein instabiler Dienstendpunkt oder eine Zeitüberschreitung.

Legen Sie eine Endbedingung fest, um endlose Wiederholungsschleifen zu vermeiden

Es empfiehlt sich, Ihre Funktion bei der Verwendung von Wiederholungsversuchen vor Endlosschleifen zu schützen. Sie können dies erreichen, indem Sie eine genau definierte Endbedingung einfügen, bevor die Funktion mit der Verarbeitung beginnt. Beachten Sie, dass diese Technik nur funktioniert, wenn Ihre Funktion erfolgreich gestartet wird und die Endbedingung auswerten kann.

Ein einfacher, aber effektiver Ansatz besteht darin, Ereignisse zu verwerfen, deren Zeitstempel älter als eine bestimmte Zeit sind. Dies trägt dazu bei, übermäßige Ausführungen zu vermeiden, wenn Fehler entweder dauerhaft sind oder länger anhalten als erwartet.

Dieses Code-Snippet verwirft beispielsweise alle Ereignisse, die älter als 10 Sekunden sind:

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

Verwenden Sie catch mit Promises

Wenn für Ihre Funktion Wiederholungsversuche aktiviert sind, löst jeder nicht behandelte Fehler einen Wiederholungsversuch aus. Stellen Sie sicher, dass Ihr Code alle Fehler erfasst, die nicht zu einem erneuten Versuch führen sollten.

Hier ist ein Beispiel dafür, was Sie tun sollten:

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

Machen Sie wiederholbare ereignisgesteuerte Funktionen idempotent

Ereignisgesteuerte Funktionen, die wiederholt werden können, müssen idempotent sein. Hier sind einige allgemeine Richtlinien, um eine solche Funktion idempotent zu machen:

  • Bei vielen externen APIs (z. B. Stripe) können Sie einen Idempotenzschlüssel als Parameter angeben. Wenn Sie eine solche API verwenden, sollten Sie die Ereignis-ID als Idempotenzschlüssel verwenden.
  • Idempotenz funktioniert gut mit der Zustellung mindestens einmal, da dadurch ein erneuter Versuch sicher ist. Daher besteht eine allgemeine Best Practice zum Schreiben zuverlässigen Codes darin, Idempotenz mit Wiederholungsversuchen zu kombinieren.
  • Stellen Sie sicher, dass Ihr Code intern idempotent ist. Zum Beispiel:
    • Stellen Sie sicher, dass Mutationen mehr als einmal auftreten können, ohne dass sich das Ergebnis ändert.
    • Fragen Sie den Datenbankstatus in einer Transaktion ab, bevor Sie den Status ändern.
    • Stellen Sie sicher, dass alle Nebenwirkungen selbst idempotent sind.
  • Erzwingen Sie eine Transaktionsprüfung außerhalb der Funktion, unabhängig vom Code. Behalten Sie beispielsweise den Status irgendwo bei und zeichnen Sie auf, dass eine bestimmte Ereignis-ID bereits verarbeitet wurde.
  • Behandeln Sie doppelte Funktionsaufrufe außerhalb des Bandes. Verwenden Sie beispielsweise einen separaten Bereinigungsprozess, der nach doppelten Funktionsaufrufen bereinigt.

Konfigurieren Sie die Wiederholungsrichtlinie

Abhängig von den Anforderungen Ihrer Cloud-Funktion möchten Sie die Wiederholungsrichtlinie möglicherweise direkt konfigurieren. Auf diese Weise können Sie eine beliebige Kombination der folgenden Elemente einrichten:

  • Verkürzen Sie das Wiederholungsfenster von 7 Tagen auf nur 10 Minuten.
  • Ändern Sie die minimale und maximale Backoff-Zeit für die exponentielle Backoff-Wiederholungsstrategie.
  • Ändern Sie die Wiederholungsstrategie, um es sofort erneut zu versuchen.
  • Konfigurieren Sie ein Thema für unzustellbare Nachrichten .
  • Legen Sie eine maximale und minimale Anzahl von Zustellversuchen fest.

So konfigurieren Sie die Wiederholungsrichtlinie:

  1. Schreiben Sie eine HTTP-Funktion.
  2. Verwenden Sie die Pub/Sub-API, um ein Pub/Sub-Abonnement zu erstellen, und geben Sie dabei die URL der Funktion als Ziel an.

Weitere Informationen zur direkten Konfiguration von Pub/Sub finden Sie in der Pub/Sub-Dokumentation zur Fehlerbehandlung .