Vernetzung optimieren

Dank der Einfachheit von Cloud Functions können Sie Code schnell entwickeln und in einer serverlosen Umgebung ausführen. Bei moderatem Umfang sind die Kosten für die Ausführung von Funktionen gering, und die Optimierung Ihres Codes scheint möglicherweise keine hohe Priorität zu haben. Wenn Ihre Bereitstellung jedoch skaliert wird, wird die Optimierung Ihres Codes immer wichtiger.

Dieses Dokument beschreibt, wie Sie das Netzwerk für Ihre Funktionen optimieren können. Einige der Vorteile der Optimierung von Netzwerken sind wie folgt:

  • Reduzieren Sie die CPU-Zeit, die für den Aufbau neuer Verbindungen bei jedem Funktionsaufruf aufgewendet wird.
  • Reduzieren Sie die Wahrscheinlichkeit, dass die Verbindungs- oder DNS- Kontingente erschöpft sind.

Beständige Verbindungen aufrechterhalten

Dieser Abschnitt enthält Beispiele dafür, wie dauerhafte Verbindungen in einer Funktion aufrechterhalten werden. Andernfalls können die Verbindungskontingente schnell erschöpft sein.

Die folgenden Szenarien werden in diesem Abschnitt behandelt:

  • HTTP/S
  • Google-APIs

HTTP/S-Anfragen

Das optimierte Code-Snippet unten zeigt, wie man dauerhafte Verbindungen aufrechterhält, anstatt bei jedem Funktionsaufruf eine neue Verbindung zu erstellen:

const http = require('http');
const functions = require('firebase-functions');

// Setting the `keepAlive` option to `true` keeps
// connections open between function invocations
const agent = new http.Agent({keepAlive: true});

exports.function = functions.https.onRequest((request, response) => {
    req = http.request({
        host: '',
        port: 80,
        path: '',
        method: 'GET',
        agent: agent, // Holds the connection open after the first invocation
    }, res => {
        let rawData = '';
        res.setEncoding('utf8');
        res.on('data', chunk => { rawData += chunk; });
        res.on('end', () => {
            response.status(200).send(`Data: ${rawData}`);
        });
    });
    req.on('error', e => {
        response.status(500).send(`Error: ${e.message}`);
    });
    req.end();
});

Zugriff auf Google-APIs

Im folgenden Beispiel wird Cloud Pub/Sub verwendet, aber dieser Ansatz funktioniert auch für andere Clientbibliotheken, z. B. Cloud Natural Language oder Cloud Spanner . Beachten Sie, dass Leistungsverbesserungen von der aktuellen Implementierung bestimmter Client-Bibliotheken abhängen können.

Das Erstellen eines PubSub -Clientobjekts führt zu einer Verbindung und zwei DNS-Abfragen pro Aufruf. Um unnötige Verbindungen und DNS-Abfragen zu vermeiden, erstellen Sie das PubSub Client-Objekt im globalen Bereich, wie im folgenden Beispiel gezeigt:

const PubSub = require('@google-cloud/pubsub');
const functions = require('firebase-functions');
const pubsub = PubSub();

exports.function = functions.https.onRequest((req, res) => {
    const topic = pubsub.topic('');

    topic.publish('Test message', err => {
        if (err) {
            res.status(500).send(`Error publishing the message: ${err}`);
        } else {
            res.status(200).send('1 message published');
        }
    });
});

Belastungstest Ihrer Funktion

Um zu messen, wie viele Verbindungen Ihre Funktion im Durchschnitt ausführt, stellen Sie sie einfach als HTTP-Funktion bereit und verwenden Sie ein Leistungstest-Framework, um sie bei bestimmten QPS aufzurufen. Eine mögliche Auswahl ist Artillery , die Sie mit einer einzigen Zeile aufrufen können:

$ artillery quick -d 300 -r 30 URL

Dieser Befehl ruft die angegebene URL 300 Sekunden lang mit 30 QPS ab.

Überprüfen Sie nach dem Test die Nutzung Ihres Verbindungskontingents auf der Kontingentseite der Cloud Functions-API in der Cloud Console. Wenn die Nutzung konstant um die 30 (oder ihr Vielfaches) liegt, stellen Sie bei jedem Aufruf eine (oder mehrere) Verbindungen her. Nachdem Sie Ihren Code optimiert haben, sollten nur zu Beginn des Tests einige (10–30) Verbindungen auftreten.

Sie können auch die CPU-Kosten vor und nach der Optimierung im CPU-Kontingentdiagramm auf derselben Seite vergleichen.