Wdrażanie bezserwerowych funkcji Node.js za pomocą Google Cloud
Opublikowany: 2022-03-11Tworzenie oprogramowania nie kończy się na napisaniu dobrego kodu. Ukończy się, gdy oprogramowanie zostanie wdrożone i będzie w stanie prawidłowo obsługiwać żądania oraz kiedy możemy skalować bez ograniczania wydajności i kosztów jego uruchamiania.
Prawdopodobnie myślisz o tym, w jaki sposób masz chmurę obliczeniową, aby zająć się tymi wszystkimi rzeczami. – Więc czym jest ta nowa rzecz bezserwerowa , Vignes?
Przetwarzanie bezserwerowe to styl architektury, w którym kod jest wykonywany na platformie chmury, w której nie musimy się martwić o konfigurację sprzętu i oprogramowania, bezpieczeństwo, wydajność i koszty bezczynności procesora. To postęp w przetwarzaniu w chmurze, który wykracza poza infrastrukturę, która abstrahuje również od środowiska oprogramowania. Oznacza to, że do uruchomienia kodu nie jest wymagana żadna konfiguracja.
W przypadku serverless Twój styl pracy będzie następujący:
Opracuj kod.
Prześlij kod do usługodawcy.
Skonfiguruj wyzwalacz (w naszym przypadku żądanie HTTP).
Nasza praca skończona! Teraz dostawca platformy zajmie się przychodzącymi żądaniami i skalowaniem.
Wprowadzenie do mikrousług bezserwerowych
Architektura bezserwerowa jest często połączona z projektem stylu mikrousług. Mikrousługa jest samodzielną częścią dużego oprogramowania, która obsługuje żądania dotyczące jednego konkretnego modułu. Tworząc mikrousługi, które mogą działać w środowisku bezserwerowym, łatwiej jest utrzymywać kod i przyspieszać wdrożenia.
Wprowadzenie do AWS Lambda i GCF, porównanie
Funkcja bezserwerowa jest często nazywana „zapleczem jako usługa” lub „funkcją jako usługa”. Liczba dostawców usług przetwarzania bezserwerowego zaczyna rosnąć. Jednak niektórzy z tradycyjnych dużych graczy oferują również opcje bezserwerowe, takie jak AWS Lambda Functions firmy Amazon Web Services i Google Cloud Functions (GCF) Google Cloud, z których korzystam, będąc obecnie w wersji beta. Chociaż działają podobnie, jest między nimi kilka ważnych różnic.
| AWS Lambda | Funkcje chmury Google | |
|---|---|---|
| Wsparcie językowe | Node.js, Python, C#, Java | Node.js |
| Wyzwalacze | DynamoDB, Kinesis, S3, SNS, bramka API (HTTP), CloudFront, + więcej | HTTP, Cloud PubSub, zasobnik w chmurze |
| Maksymalny czas realizacji | 300 sekund | 540 sekund |
W tym artykule omówimy proces implementacji bezserwerowego wdrażania kodu przy użyciu GCF. Google Cloud Functions to lekkie, oparte na zdarzeniach, asynchroniczne rozwiązanie obliczeniowe, które umożliwia tworzenie małych, jednofunkcyjnych funkcji, które reagują na zdarzenia w chmurze bez konieczności zarządzania serwerem lub środowiskiem wykonawczym.
GCF ma trzy możliwe implementacje rozdzielone na podstawie wyzwalaczy.
Wyzwalacz HTTP Kieruje żądania HTTP do funkcji chmury
Wewnętrzny wyzwalacz pub/sub Google Trasy publikują i żądają subskrypcji do funkcji w chmurze
Wyzwalacz zasobnika pamięci masowej Przekierowuje wszelkie zmiany wprowadzone w zasobniku pamięci masowej do funkcji chmury
Utwórzmy konfigurację opartą na wyzwalaczu HTTP za pomocą Google Cloud Functions
Google Cloud Functions nie wymaga żadnej dodatkowej specjalnej konfiguracji ani instalacji. GCF zapewnia, że domyślne środowisko węzła jest skonfigurowane i gotowe do wykonania. Gdy funkcja w chmurze jest tworzona z HTTP jako wyzwalaczem, udostępnia adres URL do wyzwalania funkcji. W porównaniu z AWS Lambda, która wykorzystuje bramę API jako medium do komunikacji z nim, Google Cloud Functions udostępnia adres URL natychmiast na podstawie identyfikatora projectID i regionu.
Tworzenie bezserwerowej aplikacji Node.js
Aby nasz kod był wykonywalny w GCF, powinniśmy owinąć go w jedną funkcję. GCF wywoła tę konkretną funkcję za każdym razem, gdy wystąpi wyzwalacz. Możliwe sposoby, aby to zrobić, to przesyłanie,
Pojedynczy plik: wyeksportuj domyślną funkcję, która wywoła inne funkcje na podstawie żądania.
Wiele plików: plik
index.jswymagający wszystkich innych plików i eksportujący funkcję domyślną jako punkt początkowy.Wiele plików: jeden główny plik skonfigurowany w
package.json, używając"main": "main.js"jako punktu początkowego.
Każda z powyższych metod będzie działać.
GCF obsługuje określoną wersję środowiska uruchomieniowego węzła. Upewnij się, że kod jest napisany w celu obsługi tej konkretnej wersji. W momencie tworzenia tego posta GCF obsługuje Node w wersji v6.11.1.
Aby utworzyć funkcję, należy rozważyć kilka opcji.
Pamięć Wskazuje, ile pamięci jest potrzebne do przetworzenia żądania w jednym czasie wykonywania. Zdefiniowane w MB. W przypadku małej aplikacji 128 MB powinno wystarczyć, ale można ją zwiększyć do 2 GB.
Limit czasu Limit czasu, jak sama nazwa wskazuje, określa oczekiwany limit czasu wykonania kodu. Po tym kod zostanie zabity i zatrzymany. Wszelkie egzekucje po tym punkcie zostaną nagle przerwane. Maksymalny limit czasu to 540 sekund.
Funkcja do wykonania Chociaż z głównego pliku obsługi można wyeksportować więcej niż jedną funkcję, musimy skonfigurować jedną funkcję, która powinna zostać wyzwolona w celu przetworzenia żądania. Dzięki temu programista może mieć wiele punktów wejścia w oparciu o metodę/adres URL HTTP.

Aby przesłać kod, po prostu skopiuj i wklej kod, aby utworzyć portal funkcji. W przypadku więcej niż jednego pliku skompresuj zawartość i prześlij plik. Upewnij się, że w przypadku pliku ZIP powinien istnieć plik index.js lub plik package.json ze wspomnianym plikiem głównym.
Każda zależność modułu NPM powinna być wymieniona w package.json . GCF próbuje zainstalować moduły wymienione w pliku package.json podczas pierwszej instalacji.
Stwórzmy prosty program do zwrócenia statusu 200 i jakiejś wiadomości. Utwórz funkcję i dodaj następujący kod do źródła.
exports.httpServer = function httpServer(req, res) { console.log(req); res.status(200).send('Server is working'); } Po utworzeniu funkcji otwórz podany adres URL, aby uruchomić funkcję. Powinien odpowiadać jak poniżej.
Przyjrzyjmy się teraz obiektowi req w dziennikach. Aby wyświetlić logi, GCF udostępnia opcje bezpośrednio z konsoli. Kliknij pionowe kropki i otwórz opcję dzienników.
Teraz zaktualizujmy kod, aby obsługiwał proste trasy dla /users .
Poniższy kod służy do obsługi prostego żądania GET & POST dla trasy /users :
exports.httpServer = function httpServer(req, res) { const path = req.path; switch(path) { case '/users': handleUsers(req, res); break; default: res.status(200).send('Server is working'); } }; const handleUsers = (req, res) => { if (req.method === 'GET') { res.status(200).send('Listing users...'); } else if (req.method === 'POST') { res.status(201).send('Creating User...') } else { res.status(404); } } Po aktualizacji przetestujmy go teraz w przeglądarce, ale tym razem z /users na końcu.
To super. Stworzyliśmy podstawowy serwer HTTP z routingiem.
Operacje i debugowanie
Gdyby ta historia zakończyła się w kodzie, nie badałbyś opcji infrastruktury, takich jak bezserwerowe aplikacje Node.js. Oto krótkie podsumowanie tego, jak zająć się typowymi zadaniami, takimi jak wdrażanie i debugowanie. Rzeczy, które programiści Node.js już robią dla innych aplikacji.
Zastosowanie:
Kod funkcji można wdrożyć na cztery sposoby.
Skopiuj wklejając kod w konsoli
Przesyłanie pliku ZIP
Wdrażanie z zasobnika pamięci w chmurze jako plik ZIP
Wdrażanie z repozytorium źródła w chmurze
Najwygodniejszą opcją jest oczywiście wdrożenie z repozytorium źródłowego.
Wezwanie:
Podczas tworzenia funkcji Konsola udostępnia URL HTTP do uruchomienia funkcji w formacie: https://<region>-<project-id>.cloudfunctions.net/<function-name>
Funkcja AWS Lambda ma problemy z zimnym startem, przez co wykonanie funkcji zajmuje dodatkowy czas na uruchomienie. Po uruchomieniu następujące egzekucje będą odpowiadać normalnie. Ten początkowy dodatkowy czas rozruchu jest określany jako zimny rozruch. Chociaż nie mamy oficjalnej dokumentacji GCF związanej z tym tematem, problemy z zimnym startem nie pojawiły się podczas naszych testów.
Debugowanie:
GCF integruje się z usługą Stackdriver Logging w Google Cloud. Wszystkie dzienniki i błędy konsoli zostaną tutaj zarejestrowane, co pomaga w debugowaniu kodu, który jest już wdrożony.
Testowanie:
Konsola udostępnia opcje testowania funkcji przez przekazanie JSON jako danych wejściowych. Funkcja zostanie wywołana z JSON jako dane wejściowe, a dane wyjściowe zostaną wyświetlone w konsoli. Żądanie (dane wejściowe) i odpowiedź są podobne do frameworka Express.js i mogą być testowane jednostkowo podczas samego procesu rozwoju. Jeśli potrzebujesz odświeżenia na temat testowania Node.js, zapoznaj się z A Node.js Guide to Really Doing Integration Tests
Ograniczenia i kolejne kroki
Korzystanie z funkcji bezserwerowych ma swoje zalety, ale wiąże się również z ograniczeniami
Blokada dostawcy: ogranicza kod, który piszemy, do jednego konkretnego usługodawcy. Przeniesienie kodu do innego dostawcy wymaga przepisania kodu z dużym wysiłkiem w kierunku migracji. Ponieważ może to być duży problem, powinniśmy być bardzo ostrożni przy wyborze usługodawcy.
Ograniczenia liczby żądań i zasobów sprzętowych: dostawcy często ograniczają liczbę równoległych żądań obsługiwanych przez funkcję na raz. Istnieją również ograniczenia pamięci. Tego typu ograniczenia można podnieść, rozmawiając z dostawcą, ale nadal będą istnieć.
Google Cloud Functions bardzo się rozwija i ulepsza. Nadal jest często ulepszany i aktualizowany, zwłaszcza w obsługiwanych językach. Jeśli planujesz korzystać z funkcji Google Cloud, miej oko na dzienniki zmian, aby uniknąć jakichkolwiek przełomowych zmian w implementacji.
Dalsza lektura na blogu Toptal Engineering:
- Praca z obsługą TypeScript i Jest: samouczek AWS SAM
