Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

Optymalizacja sieci

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Prostota Cloud Functions pozwala szybko tworzyć kod i uruchamiać go w środowisku bezserwerowym. Przy umiarkowanej skali koszt uruchamiania funkcji jest niski, a optymalizacja kodu może nie wydawać się priorytetem. Jednak wraz ze wzrostem wdrożenia optymalizacja kodu staje się coraz ważniejsza.

W tym dokumencie opisano, jak zoptymalizować sieć pod kątem Twoich funkcji. Oto niektóre korzyści płynące z optymalizacji sieci:

  • Zmniejsz czas procesora poświęcony na nawiązywanie nowych połączeń przy każdym wywołaniu funkcji.
  • Zmniejsz prawdopodobieństwo wyczerpania limitów połączeń lub limitów DNS.

Utrzymywanie trwałych połączeń

Ta sekcja zawiera przykłady utrzymywania trwałych połączeń w funkcji. Niezastosowanie się do tego może spowodować szybkie wyczerpanie limitów połączeń.

W tej sekcji omówiono następujące scenariusze:

  • HTTP/S
  • Interfejsy API Google

Żądania HTTP/S

Zoptymalizowany fragment kodu poniżej pokazuje, jak utrzymywać trwałe połączenia zamiast tworzyć nowe połączenie po każdym wywołaniu funkcji:

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();
});

Uzyskiwanie dostępu do interfejsów API Google

Poniższy przykład używa Cloud Pub/Sub , ale to podejście działa również w przypadku innych bibliotek klienckich — na przykład Cloud Natural Language lub Cloud Spanner . Należy zauważyć, że poprawa wydajności może zależeć od bieżącej implementacji poszczególnych bibliotek klienckich.

Utworzenie obiektu klienta PubSub skutkuje jednym połączeniem i dwoma zapytaniami DNS na wywołanie. Aby uniknąć niepotrzebnych połączeń i zapytań DNS, utwórz obiekt klienta PubSub w zakresie globalnym, jak pokazano w poniższym przykładzie:

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');
        }
    });
});

Testowanie obciążenia Twojej funkcji

Aby zmierzyć, ile połączeń średnio wykonuje Twoja funkcja, po prostu zaimplementuj ją jako funkcję HTTP i użyj struktury testowania wydajności, aby wywołać ją w określonym QPS. Jednym z możliwych wyborów jest Artyleria , którą możesz wywołać za pomocą jednej linii:

$ artillery quick -d 300 -r 30 URL

To polecenie pobiera podany adres URL z szybkością 30 QPS przez 300 sekund.

Po wykonaniu testu sprawdź wykorzystanie limitu połączenia na stronie Limit Cloud Functions API w Cloud Console. Jeśli użycie stale wynosi około 30 (lub ich wielokrotność), ustanawiasz jedno (lub kilka) połączeń w każdym wywołaniu. Po zoptymalizowaniu kodu powinieneś zauważyć, że kilka (10-30) połączeń pojawia się dopiero na początku testu.

Można również porównać koszt procesora przed i po optymalizacji na wykresie przydziału procesora na tej samej stronie.