Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Tipps

In diesem Dokument werden Best Practices für das Entwerfen, Implementieren, Testen und Bereitstellen von Cloud Functions beschrieben.

Richtigkeit

In diesem Abschnitt werden allgemeine Best Practices für das Entwerfen und Implementieren von Cloud Functions beschrieben.

idempotente Funktionen schreiben

Ihre Funktionen sollten das gleiche Ergebnis liefern, auch wenn sie mehrmals aufgerufen werden. Auf diese Weise können Sie einen Aufruf wiederholen, wenn der vorherige Aufruf mitten im Code fehlschlägt. Weitere Informationen finden Sie Retrying Hintergrundfunktionen .

Keine Hintergrundaktivitäten starten

Hintergrundaktivität ist alles, was passiert, nachdem Ihre Funktion beendet wurde. Ein Funktionsaufruf beendet , sobald die Funktion zurückkehrt oder auf andere Weise signalisiert , Beendigung, wie beispielsweise durch das anrufenden callback Argument in Node.js Hintergrundfunktionen. Jeder Code, der nach einer ordnungsgemäßen Beendigung ausgeführt wird, kann nicht auf die CPU zugreifen und macht keinen Fortschritt.

Wenn ein nachfolgender Aufruf in derselben Umgebung ausgeführt wird, wird Ihre Hintergrundaktivität außerdem wieder aufgenommen und stört den neuen Aufruf. Dies kann zu unerwartetem Verhalten und schwer zu diagnostizierenden Fehlern führen. Zugriff auf das Netz , nachdem eine Funktion beendet führt in der Regel zu Verbindungen zurückgesetzt (wobei ECONNRESET Fehlercode).

Hintergrundaktivitäten können oft in Protokollen einzelner Aufrufe erkannt werden, indem man alles findet, was nach der Zeile, die besagt, dass der Aufruf beendet ist, protokolliert wird. Hintergrundaktivitäten können manchmal tiefer im Code vergraben sein, insbesondere wenn asynchrone Vorgänge wie Rückrufe oder Zeitgeber vorhanden sind. Überprüfen Sie Ihren Code, um sicherzustellen, dass alle asynchronen Vorgänge abgeschlossen sind, bevor Sie die Funktion beenden.

Temporäre Dateien immer löschen

Der lokale Plattenspeicher im temporären Verzeichnis ist ein In-Memory-Dateisystem. Dateien, die Sie schreiben, verbrauchen Speicher, der Ihrer Funktion zur Verfügung steht, und bleiben manchmal zwischen Aufrufen bestehen. Wenn diese Dateien nicht explizit gelöscht werden, kann dies möglicherweise zu einem Fehler wegen unzureichendem Speicher und einem anschließenden Kaltstart führen.

Sie können den Speicher durch eine individuelle Funktion sehen , indem sie es in der Auswahlliste von Funktionen in der GCP - Konsole und die Wahl der Speichernutzung Grundstück.

Versuchen Sie nicht, außerhalb des temporären Verzeichnisses zu schreiben, und verwenden Sie plattform-/betriebssystemunabhängige Methoden, um Dateipfade zu erstellen.

Sie können den Speicherbedarf reduzieren, wenn Sie größere Dateien mit Pipelining verarbeiten. Sie können beispielsweise eine Datei in Cloud Storage verarbeiten, indem Sie einen Lesestream erstellen, ihn durch einen streambasierten Prozess übergeben und den Ausgabestream direkt in Cloud Storage schreiben.

Werkzeuge

Dieser Abschnitt enthält Richtlinien zur Verwendung von Tools zum Implementieren, Testen und Interagieren mit Cloud Functions.

Lokale Entwicklung

Die Funktionsbereitstellung nimmt etwas Zeit in Anspruch, daher ist es oft schneller, den Code Ihrer Funktion lokal zu testen.

Firebase - Entwickler können die Verwendung Firebase CLI Cloud - Funktionen Emulator .

Verwenden Sie Sendgrid, um E-Mails zu senden

Cloud Functions lässt keine ausgehenden Verbindungen über Port 25 zu, sodass Sie keine unsicheren Verbindungen zu einem SMTP-Server herstellen können. Der empfohlene Weg E - Mails zu senden ist zu verwenden SendGrid . Sie können andere Optionen finden in der E - Mail schreiben Senden E - Mail von einer Instanz Tutorial für Google Compute Engine.

Leistung

In diesem Abschnitt werden Best Practices zur Leistungsoptimierung beschrieben.

Verwenden Sie Abhängigkeiten mit Bedacht

Da Funktionen staatenlos sind, wird die Ausführungsumgebung oft von Grund auf neu initialisiert (während der so genannten Kaltstart bekannt ist). Bei einem Kaltstart wird der globale Kontext der Funktion ausgewertet.

Wenn Ihre Funktionen Module importieren, kann die Ladezeit für diese Module die Aufruflatenz während eines Kaltstarts erhöhen. Sie können diese Latenzzeit sowie die zum Bereitstellen Ihrer Funktion erforderliche Zeit reduzieren, indem Sie Abhängigkeiten korrekt laden und Abhängigkeiten, die Ihre Funktion nicht verwendet, nicht laden.

Verwenden Sie globale Variablen, um Objekte in zukünftigen Aufrufen wiederzuverwenden

Es gibt keine Garantie dafür, dass der Status einer Cloud Functions-Funktion für zukünftige Aufrufe beibehalten wird. Cloud Functions recycelt jedoch häufig die Ausführungsumgebung eines vorherigen Aufrufs. Wenn Sie eine Variable im globalen Gültigkeitsbereich deklarieren, kann ihr Wert in nachfolgenden Aufrufen wiederverwendet werden, ohne dass sie neu berechnet werden muss.

Auf diese Weise können Sie Objekte zwischenspeichern, deren Neuerstellung bei jedem Funktionsaufruf teuer sein kann. Das Verschieben solcher Objekte aus dem Funktionskörper in den globalen Geltungsbereich kann zu erheblichen Leistungsverbesserungen führen. Das folgende Beispiel erstellt ein schweres Objekt nur einmal pro Funktionsinstanz und teilt es für alle Funktionsaufrufe, die die angegebene Instanz erreichen:

console.log('Global scope');
const perInstance = heavyComputation();
const functions = require('firebase-functions');

exports.function = functions.https.onRequest((req, res) => {
    console.log('Function invocation');
    const perFunction = lightweightComputation();

    res.send(`Per instance: ${perInstance}, per function: ${perFunction}`);
});

Es ist besonders wichtig, Netzwerkverbindungen, Bibliotheksverweise und API-Clientobjekte im globalen Bereich zwischenzuspeichern. Siehe Optimizing Networking für Beispiele.

Führen Sie eine träge Initialisierung globaler Variablen durch

Wenn Sie Variablen im globalen Gültigkeitsbereich initialisieren, wird der Initialisierungscode immer über einen Kaltstartaufruf ausgeführt, wodurch die Latenz Ihrer Funktion erhöht wird. In bestimmten Fällen führt dies zu intermittierenden Timeouts auf die Dienste , wenn sie nicht in geeigneter Weise in einem behandelt genannt werden , werden try / catch - Block. Wenn einige Objekte nicht in allen Codepfaden verwendet werden, sollten Sie erwägen, sie bei Bedarf träge zu initialisieren:

const functions = require('firebase-functions');
let myCostlyVariable;

exports.function = functions.https.onRequest((req, res) => {
    doUsualWork();
    if(unlikelyCondition()){
        myCostlyVariable = myCostlyVariable || buildCostlyVariable();
    }
    res.status(200).send('OK');
});

Dies ist besonders wichtig, wenn Sie mehrere Funktionen in einer einzigen Datei definieren und verschiedene Funktionen unterschiedliche Variablen verwenden. Wenn Sie keine verzögerte Initialisierung verwenden, können Sie Ressourcen für Variablen verschwenden, die initialisiert, aber nie verwendet werden.

Reduzieren Sie Kaltstarts, indem Sie eine Mindestanzahl von Instanzen festlegen

Standardmäßig skaliert Cloud Functions die Anzahl der Instanzen basierend auf der Anzahl der eingehenden Anfragen. Sie können dieses Standardverhalten ändern, indem Sie eine Mindestanzahl von Instanzen festlegen, die Cloud Functions für die Bearbeitung von Anfragen bereithalten muss. Das Festlegen einer Mindestanzahl von Instanzen reduziert Kaltstarts Ihrer Anwendung. Wir empfehlen, eine Mindestanzahl von Instanzen festzulegen, wenn Ihre Anwendung latenzsensitiv ist.

Siehe Skalierung Regelverhalten für weitere Informationen über diese Laufzeitoptionen.

Zusätzliche Ressourcen

Erfahren Sie mehr über die Optimierung der Leistung in den "Google Cloud Performance - Atlas" Video Cloud - Funktionen Cold Boot - Zeit .