Asynchrone Funktionen wiederholen

In diesem Dokument wird beschrieben, wie Sie asynchrone Anfragen (Nicht-HTTPS) anfordern können. Hintergrundfunktionen, die bei einem Fehler wiederholt werden sollen.

Semantik von Wiederholungsversuchen

Cloud Functions ermöglicht die mindestens einmalige Ausführung einer ereignisgesteuerten Funktion für jedes von einer Ereignisquelle ausgegebene Ereignis. Wenn ein Funktionsaufruf mit einem Fehler beendet wird, wird die Funktion standardmäßig nicht noch einmal aufgerufen und das Ereignis wird verworfen. Wenn Sie Wiederholungsversuche für eine ereignisgesteuerte Funktion aktivieren, wiederholt Cloud Functions einen fehlgeschlagenen Funktionsaufruf, bis der Vorgang erfolgreich abgeschlossen wurde oder der Wiederholungszeitraum abläuft.

Bei Funktionen der 2. Generation läuft dieses Wiederholungsfenster nach 24 Stunden ab. Bei Funktionen der 1. Generation läuft es nach sieben Tagen ab. Cloud Functions wiederholt neu erstellte ereignisgesteuerte Funktionen mit einer Strategie mit exponentiellem Backoff mit einem zunehmenden Backoff zwischen 10 und 600 Sekunden. Diese Richtlinie wird bei der ersten Bereitstellung auf neue Funktionen angewendet. Sie wird nicht rückwirkend auf bestehende Funktionen, die vor den im folgenden Abschnitt beschriebenen Änderungen bereitgestellt wurden: diesen Versionshinweisen selbst wenn Sie die Funktionen noch einmal bereitstellen.

Wenn Wiederholungsversuche nicht für eine Funktion aktiviert sind (Standardeinstellung), meldet die Funktion immer, dass sie erfolgreich ausgeführt wurde. In den Logs können auch 200 OK-Antwortcodes angezeigt werden. Dies tritt auch dann auf, wenn bei der Funktion ein Fehler aufgetreten ist. Um deutlich zu machen, wann Ihre Funktion einen Fehler feststellt, müssen Sie Fehler entsprechend melden.

Warum ereignisgesteuerte Funktionen nicht abgeschlossen werden

In seltenen Fällen kann eine Funktion aufgrund eines internen Fehlers vorzeitig beendet werden. Je nach angegebener Standardeinstellung für diese Funktion werden dann Wiederholungsversuche mit der Funktion durchgeführt oder nicht.

Typischer ist das Fehlschlagen einer ereignisgesteuerten Funktion aufgrund von Fehlern, die im Funktionscode selbst ausgegeben werden. Dies kann 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 überschreitet während des Versuchs eine Zeitüberschreitung.
  • 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 Nicht-null-Wert an einen Callback.

In jedem dieser Fälle stoppt die Funktion standardmäßig die Ausführung und das Ereignis wird verworfen. Um die Funktion bei einem Fehler noch einmal zu versuchen, können Sie die Standardrichtlinie für Wiederholungsversuche ändern, indem Sie das Attribut "Bei Fehler noch einmal versuchen" festlegen. Dadurch wird das Ereignis wiederholt, bis die Funktion erfolgreich abgeschlossen wurde oder das Zeitlimit für Wiederholungsversuche abläuft.

Wiederholungsversuche aktivieren oder deaktivieren

Wiederholungsversuche über die Console konfigurieren

Wenn Sie eine neue Funktion erstellen, gehen Sie so vor:

  1. Wählen Sie im Funktion erstellen, unter Trigger und wählen Sie den Ereignistyp aus, der als Trigger für den .
  2. Klicken Sie das Kästchen Bei Fehler noch einmal versuchen an, um Wiederholungsversuche zu aktivieren.

Wenn Sie eine vorhandene Funktion aktualisieren:

  1. Klicken Sie auf der Seite Cloud Functions auf den Namen des aktualisieren, um den Bildschirm Funktionsdetails zu öffnen, und dann Wählen Sie in der Menüleiste Bearbeiten aus, um den Bereich Trigger aufzurufen.
  2. Aktivieren oder deaktivieren Sie das Kästchen Bei Fehler noch einmal versuchen, um Wiederholungsversuche zu aktivieren oder zu deaktivieren.

Wiederholungsversuche über den Funktionscode konfigurieren

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

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

Wenn Sie true so festlegen, wird eine Funktion konfiguriert, die bei einem Fehler noch einmal versucht wird.

Best Practices

In diesem Abschnitt werden Best Practices für den Einsatz von Wiederholungsversuchen beschrieben.

Wiederholungsversuche zur Behebung vorübergehender Fehler verwenden

Da Ihre Funktion bis zur erfolgreichen Ausführung kontinuierlich wiederholt wird, sollten Sie vor dem Aktivieren von Wiederholungsversuchen permanente Fehler wie Programmfehler mithilfe von Tests im Code beseitigen. Wiederholungsversuche eignen sich am besten bei zeitweiligen oder vorübergehenden Fehler, bei denen die Wahrscheinlichkeit, dass sie nach einem Wiederholungsversuch gelöst werden, sehr hoch ist, z. B. unzuverlässigen Dienstendpunkt oder Zeitüberschreitung.

Endbedingung festlegen, um Endlosschleifen zu verhindern

Beim Einsatz von Wiederholungsversuchen ist es eine Best Practice, die Funktion vor Endlosschleifen zu schützen. Dies erreichen Sie beispielsweise, indem Sie eine gut definierte Endbedingung einfügen, bevor die Verarbeitung der Funktion beginnt. Beachten Sie, dass diese Methode nur funktioniert, wenn Ihre Funktion erfolgreich gestartet wird und die Endbedingung auswerten kann.

Ein einfacher, aber effektiver Ansatz ist, Ereignisse zu verwerfen, deren Zeitstempel älter als ein bestimmtes Datum ist. Dadurch werden übermäßig viele Ausführungen verhindert, wenn Fehler entweder persistent oder langlebiger als erwartet sind.

Beispielsweise werden durch dieses Code-Snippet alle Ereignisse verworfen, 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;
}

catch mit Promises verwenden

Wenn für Ihre Funktion Wiederholungsversuche aktiviert sind, löst jeder nicht aufgelöste Fehler einen Wiederholungsversuch aus. Achten Sie darauf, dass in Ihrem Code alle Fehler erfasst werden, 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);
});

Wiederholbare ereignisgesteuerte Funktionen idempotent machen

Ereignisgesteuerte Funktionen, für die Wiederholungsversuche gemacht werden können, müssen idempotent sein. Hier sind einige allgemeine Richtlinien, wie Sie eine solche Funktion idempotent machen:

  • Bei vielen externen APIs (z. B. Stripe) können Sie einen Idempotenzschlüssel als Parameter bereitstellen. Wenn Sie eine solche API verwenden, sollten Sie die Ereignis-ID als Idempotenzschlüssel verwenden.
  • Idempotenz funktioniert gut bei mindestens einmaliger Übermittlung, weil Wiederholungsversuche dadurch problemlos erfolgen können. Eine allgemeine Best Practice für das Schreiben von zuverlässigem Code ist also, Idempotenz mit Wiederholungsversuchen zu kombinieren.
  • Achten Sie darauf, dass der Code intern idempotent ist. Beispiele:
    • Sorgen Sie dafür, dass Mutationen mehr als einmal passieren können, ohne das Ergebnis zu verändern.
    • Fragen Sie den Datenbankstatus in einer Transaktion ab, bevor der Status mutiert wird.
    • Stellen Sie sicher, dass alle Nebenwirkungen selbst idempotent sind.
  • Erzwingen Sie eine Transaktionsprüfung außerhalb der Funktion und unabhängig vom Code. Beispiel: Zustand an einem Punkt persistent machen, um aufzuzeichnen, dass eine bestimmte Ereignis-ID bereits verarbeitet wurde.
  • Nutzen Sie ein Verfahren für doppelte Funktionsaufrufe "out of band". Verwenden Sie beispielsweise einen separaten Bereinigungsprozess, der nach doppelten Funktionsaufrufen eine Bereinigung durchführt.

Wiederholungsrichtlinie konfigurieren

Je nach den Anforderungen Ihrer Funktion können Sie Wiederholungsrichtlinie direkt wiederholen. Auf diese Weise können Sie eine beliebige Kombination Folgendes:

  • Verkürzen Sie den Wiederholungszeitraum von 7 Tagen auf nur 10 Minuten.
  • Ändern Sie die minimale und maximale Wartezeit für die Wiederholungsstrategie mit exponentiellem Backoff.
  • Ändern Sie die Wiederholungsstrategie so, dass umgehend ein erneuter Versuch unternommen wird.
  • Konfigurieren Sie ein Thema für unzustellbare Nachrichten.
  • Legen Sie eine maximale und eine minimale Anzahl von Übermittlungsversuchen fest.

So konfigurieren Sie die Wiederholungsrichtlinie:

  1. Schreiben Sie eine HTTP-Funktion.
  2. Verwenden Sie die Pub/Sub API, um ein Pub/Sub-Abo zu erstellen. Geben Sie dabei die URL von die Funktion als Ziel.

Siehe Pub/Sub-Dokumentation zur Fehlerbehandlung finden Sie weitere Informationen zur direkten Konfiguration von Pub/Sub.