Catch up on everthing we announced at this year's Firebase Summit. Learn more

Wiederholen Sie asynchrone Funktionen

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

Semantik der Wiederholung

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

Warum ereignisgesteuerte Funktionen nicht ausgeführt werden können

In seltenen Fällen kann eine Funktion aufgrund eines internen Fehlers vorzeitig beendet werden, und standardmäßig wird die Funktion möglicherweise automatisch wiederholt.

Typischerweise kann eine ereignisgesteuerte Funktion aufgrund von Fehlern im Funktionscode selbst nicht erfolgreich abgeschlossen werden. Einige der Gründe dafür, dass dies passieren kann, sind wie folgt:

  • Die Funktion enthält einen Fehler und die Laufzeit löst eine Ausnahme aus.
  • Die Funktion kann einen Dienstendpunkt nicht erreichen oder beim Versuch, den Endpunkt zu erreichen, läuft eine Zeitüberschreitung ab.
  • Die Funktion löst absichtlich eine Ausnahme aus (z. B. wenn die Validierung eines Parameters fehlschlägt).
  • Wenn Funktionen in Node.js geschrieben zurückgeben abgelehnt Versprechen oder ein nicht passieren null auf einen Rückruf.

In jedem der oben genannten Fälle wird die Funktion standardmäßig nicht mehr ausgeführt und das Ereignis wird verworfen. Wenn Sie die Funktion erneut zu versuchen sollen , wenn ein Fehler auftritt, können Sie die Richtlinie Standardwiederholungs ändern , indem Sie die „Wiederholungs auf Fehler“ Eigenschaft festlegen . Dies führt dazu, dass das Ereignis bis zu mehreren Tagen wiederholt wiederholt wird, bis die Funktion erfolgreich abgeschlossen wurde.

Aktivieren und Deaktivieren von Wiederholungen

Verwenden der GCP Console

Sie können Wiederholungsversuche in der GCP Console wie folgt aktivieren oder deaktivieren:

  1. Gehen Sie auf die Cloud - Funktionen Übersicht Seite in der Cloud Platform Console.

  2. Klicken Sie auf Funktion erstellen. Alternativ klicken Sie auf eine vorhandene Funktion die Detailseite zu gehen und klicken Sie auf Bearbeiten.

  3. Füllen Sie die erforderlichen Felder für Ihre Funktion aus.

  4. Sicherstellen , dass das Trigger - Feld auf einen ereignisbasierte Trigger - Typen, wie Cloud Pub / Sub oder Cloud Storage.

  5. Erweitern Sie die erweiterten Einstellungen von Mehr klicken.

  6. Aktivieren oder deaktivieren Sie das Kontrollkästchen Wiederholen eines Fehler auftritt .

Im Funktionscode

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

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

Einstellen true als eine Funktion Wiederholungs bei einem Fehler gezeigt konfiguriert.

Empfohlene Vorgehensweise

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

Verwenden Sie den Wiederholungsversuch, um vorübergehende Fehler zu behandeln

Da Ihre Funktion bis zur erfolgreichen Ausführung kontinuierlich wiederholt wird, sollten permanente Fehler wie Bugs durch Tests aus Ihrem Code entfernt werden, bevor Wiederholungen aktiviert werden. Wiederholungen werden am besten verwendet, um zeitweilige/vorübergehende Fehler zu behandeln, die bei einem erneuten Versuch mit hoher Wahrscheinlichkeit behoben werden, wie z. B. ein flockiger Dienstendpunkt oder eine Zeitüberschreitung.

Legen Sie eine Endbedingung fest, um Endlosschleifen zu vermeiden

Es empfiehlt sich, Ihre Funktion bei der Verwendung von Wiederholungen vor Endlosschleifen zu schützen. Sie können dies tun , indem Sie einen gut definierten Endzustand einschließlich, bevor die Funktion 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 mit Zeitstempeln zu verwerfen, die ä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 dauern 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 Wiederholungen aktiviert sind, wird jeder nicht behandelte Fehler einen Wiederholungsversuch auslösen. Stellen Sie sicher, dass Ihr Code alle Fehler erfasst, die nicht zu einem Wiederholungsversuch 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 (wie 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 einer mindestens einmaligen Lieferung, da es sicher ist, es erneut zu versuchen. Eine allgemeine bewährte Methode zum Schreiben von zuverlässigem Code besteht daher 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 das Ergebnis zu ändern.
    • Fragen Sie den Datenbankstatus in einer Transaktion ab, bevor Sie den Status ändern.
    • Stellen Sie sicher, dass alle Nebenwirkungen selbst idempotent sind.
  • Führen Sie unabhängig vom Code eine Transaktionsprüfung außerhalb der Funktion durch. Persistieren Sie beispielsweise irgendwo, dass eine bestimmte Ereignis-ID bereits verarbeitet wurde.
  • Umgang mit doppelten Funktionsaufrufen außerhalb des Bandes. Verwenden Sie beispielsweise einen separaten Bereinigungsprozess, der nach doppelten Funktionsaufrufen bereinigt.