Porady & Triki

W tym dokumencie opisano sprawdzone metody projektowania, wdrażania, testowania i wdrażania Cloud Functions.

Poprawność

W tej sekcji opisano ogólne sprawdzone metody projektowania i wdrażania Cloud Functions.

Napisz idempotentne funkcje

Twoje funkcje powinny dawać ten sam wynik, nawet jeśli są wywoływane wielokrotnie. Dzięki temu możesz ponowić wywołanie, jeśli poprzednie wywołanie nie powiedzie się w połowie kodu. Aby uzyskać więcej informacji, zobacz Ponowna próba funkcje tła .

Nie rozpoczynaj działań w tle

Aktywność w tle to wszystko, co dzieje się po zakończeniu funkcji. Funkcja wywołania zakończy po powrocie funkcyjnych lub inaczej sygnalizuje zakończenie, takie jak wywołując callback argument node.js funkcji tła. Żaden kod uruchomiony po łagodnym zakończeniu nie może uzyskać dostępu do procesora i nie spowoduje żadnego postępu.

Ponadto, gdy kolejne wywołanie jest wykonywane w tym samym środowisku, aktywność w tle jest wznawiana, zakłócając nowe wywołanie. Może to prowadzić do nieoczekiwanych zachowań i błędów, które są trudne do zdiagnozowania. Dostępu do sieci po wygaśnięciem funkcji prowadzi zazwyczaj do połączeń zerują ( ECONNRESET kod błędu).

Aktywność w tle można często wykryć w dziennikach poszczególnych wywołań, znajdując wszystko, co jest rejestrowane po wierszu informującym o zakończeniu wywołania. Aktywność w tle może czasami być pochowana głębiej w kodzie, zwłaszcza gdy występują operacje asynchroniczne, takie jak wywołania zwrotne lub czasomierze. Przejrzyj swój kod, aby upewnić się, że wszystkie operacje asynchroniczne kończą się przed zakończeniem funkcji.

Zawsze usuwaj pliki tymczasowe

Lokalna pamięć dyskowa w katalogu tymczasowym to system plików w pamięci. Pliki, które zapisujesz, zużywają pamięć dostępną dla Twojej funkcji i czasami utrzymują się między wywołaniami. Niepowodzenie w jawnym usunięciu tych plików może ostatecznie doprowadzić do błędu braku pamięci i późniejszego zimnego startu.

Można zobaczyć pamięć używaną przez indywidualną funkcję, wybierając ją w liście funkcji w GCP konsoli i wybierając działkę wykorzystanie pamięci.

Nie próbuj pisać poza katalogiem tymczasowym i upewnij się, że do konstruowania ścieżek plików używasz metod niezależnych od platformy/systemu operacyjnego.

Możesz zmniejszyć wymagania dotyczące pamięci podczas przetwarzania większych plików za pomocą potoku. Na przykład możesz przetworzyć plik w Cloud Storage, tworząc strumień odczytu, przekazując go przez proces oparty na strumieniu i zapisując strumień wyjściowy bezpośrednio w Cloud Storage.

Narzędzia

Ta sekcja zawiera wskazówki dotyczące korzystania z narzędzi do implementacji, testowania i interakcji z Cloud Functions.

Rozwój lokalny

Wdrażanie funkcji zajmuje trochę czasu, więc często szybciej jest przetestować kod funkcji lokalnie.

Firebase programiści mogą korzystać z funkcji Firebase CLI Chmura Emulator .

Użyj Sendgrid do wysyłania e-maili

Cloud Functions nie zezwala na połączenia wychodzące na porcie 25, więc nie można nawiązywać niezabezpieczonych połączeń z serwerem SMTP. Zalecany sposób wysyłania wiadomości e-mail jest użycie SendGrid . Można znaleźć inne opcje wysyłania wiadomości e-mail na wysyłanie e-maili z instancją poradniku dla Google Compute Engine.

Wydajność

W tej sekcji opisano najlepsze rozwiązania dotyczące optymalizacji wydajności.

Mądrze korzystaj z zależności

Ponieważ funkcje bezstanowy, środowisko wykonawcze jest często inicjowane od zera (w czasie, co jest znane jako rozruchu na zimno). Gdy wystąpi zimny start, oceniany jest globalny kontekst funkcji.

Jeśli funkcje importują moduły, czas ładowania tych modułów może zwiększyć opóźnienie wywołania podczas zimnego startu. Możesz zmniejszyć to opóźnienie, a także czas potrzebny do wdrożenia funkcji, poprawnie ładując zależności i nie ładując zależności, których nie używa funkcja.

Zmniejsz liczbę zimnych startów, ustawiając minimalną liczbę wystąpień

Domyślnie Cloud Functions skaluje liczbę instancji na podstawie liczby przychodzących żądań. Możesz zmienić to domyślne zachowanie, ustawiając minimalną liczbę instancji, które Cloud Functions musi utrzymywać w gotowości do obsługi żądań. Ustawienie minimalnej liczby wystąpień zmniejsza zimny start aplikacji. Zalecamy ustawienie minimalnej liczby wystąpień, jeśli aplikacja jest wrażliwa na opóźnienia.

Zobacz zachowania skalowania sterowania , aby uzyskać więcej informacji na temat tych opcji uruchomieniowych.

Użyj zmiennych globalnych, aby ponownie użyć obiektów w przyszłych wywołaniach

Nie ma gwarancji, że stan funkcji w chmurze zostanie zachowany dla przyszłych wywołań. Jednak Cloud Functions często odtwarza środowisko wykonawcze poprzedniego wywołania. Jeśli zadeklarujesz zmienną w zakresie globalnym, jej wartość może zostać ponownie wykorzystana w kolejnych wywołaniach bez konieczności ponownego obliczania.

W ten sposób możesz buforować obiekty, których odtworzenie może być kosztowne przy każdym wywołaniu funkcji. Przeniesienie takich obiektów z treści funkcji do zakresu globalnego może spowodować znaczną poprawę wydajności. Poniższy przykład tworzy ciężki obiekt tylko raz na instancję funkcji i udostępnia go we wszystkich wywołaniach funkcji docierających do danej instancji:

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

Szczególnie ważne jest buforowanie połączeń sieciowych, odwołań do bibliotek i obiektów klientów API w zakresie globalnym. Zobacz Optymalizacja Networking przykłady.

Wykonaj leniwą inicjalizację zmiennych globalnych

Jeśli zainicjujesz zmienne w zakresie globalnym, kod inicjujący będzie zawsze wykonywany przez wywołanie zimnego startu, zwiększając opóźnienie funkcji. W niektórych przypadkach powoduje to sporadyczne limity czasu do usług miano jeśli nie są prawidłowo obsługiwane w try / catch bloku. Jeśli niektóre obiekty nie są używane we wszystkich ścieżkach kodu, rozważ inicjowanie ich leniwie na żądanie:

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

Jest to szczególnie ważne, jeśli definiujesz kilka funkcji w jednym pliku, a różne funkcje używają różnych zmiennych. Jeśli nie używasz inicjalizacji z opóźnieniem, możesz marnować zasoby na zmienne, które są inicjowane, ale nigdy nie są używane.

Zmniejsz liczbę zimnych startów, ustawiając minimalną liczbę wystąpień

Domyślnie Cloud Functions skaluje liczbę instancji na podstawie liczby przychodzących żądań. Możesz zmienić to domyślne zachowanie, ustawiając minimalną liczbę instancji, które Cloud Functions musi utrzymywać w gotowości do obsługi żądań. Ustawienie minimalnej liczby wystąpień zmniejsza zimny start aplikacji. Zalecamy ustawienie minimalnej liczby wystąpień, jeśli aplikacja jest wrażliwa na opóźnienia.

Dodatkowe zasoby

Dowiedzieć się więcej na temat optymalizacji wydajności w „Google Cloud Atlas” Wydajność wideo Funkcje chmura starcie systemu .