Ten wpis jest drugą częścią artykułu poświęconego na wstęp do Google Cloud Functions. W tym wpisie przejdziemy sobie krok po kroku przez proces tworzenia i uruchamiania Cloud Functions w infrastrukturze Google Cloud Platform. Funkcją, którą utworzymy sobie w ramach tego wpisu będzie HTTP Functions, a do jej napisania wykorzystamy środowisk Node.js w wersji 8. Przed przystąpieniem do działania zachęcamy do zapoznania się z pierwszą częścią tego wpisu poświęconego na teoretyczne wprowadzenie do Cloud Functions. Przybliżone zostały w nim podstawowe informacje, które mogą być niezbędne do zrozumienia tego co będzie robić w dalszej części.
Wstępna konfiguracja
Do pracy z Cloud Functions potrzebujemy oczywiście aktywnego kont w Google Cloud Platform wraz z skonfigurowanym na nim kontem Bilingowym. Jeśli jeszcze nie założyłeś swojego konta w GCP to zachęcamy Cię do tego, tutaj link z instrukcją. Przed przystąpieniem do pracy z Cloud Functions sugeruje, aby utworzyć dedykowany projekt w ramach którego będziemy tworzyć nasze testowe funkcje. Kategoryzowanie zasobów w projekty, ułatwia znaczenia późniejsze zarządzanie nimi.
Uruchamianie funkcji z interfejsu Cloud Functions
Pierwszym ze sposobów na utworzenie nowej funkcji jest po prostu wykorzystanie przeglądarkowej konsoli GCP. W tym celu w głównym menu znajdującym się po prawej stronie wyszukujemy usługę Cloud Functions i przechodzimy do niej. Polecam przypięcie sobie tej usługi do ulubionych poprzez kliknięcie w pina. Możemy również wykorzystać wyszukiwarkę znajdującą się na środku głównej belki nawigacyjnej.
Po przejściu na zakładkę Cloud Functions możemy od razu przejść do wizarda klikając Create Function
Wizard do którego przejdziemy będzie już uzupełniony o domyślną konfigurację wraz z przykładowym kodem funkcji zwracającej nam Hello World :). W tym artykule pójdziemy jednak o krok dalej i nie będziemy uruchamiać funkcji poprzez wizarda a wykorzystam do tego CLI gcloud. Na tym etapie omówimy sobie jedynie parametry konfiguracyjne powyższego wizarda dla Cloud Functions:
- Name – nazwa naszej funkcji. Musi być unikalna wśród listy naszych funkcji. Nie jest to jednak identyfikator unikalny w całej infrastrukturze GCP
- Memory – ilość pamięci operacyjnej, która ma zostać przydzielona naszej funkcji. Zakres od 256MB – 2 GB. Wraz z wielkością tej wartości GCP przydziela również adekwatną wartość CPU.
- Trigger – określamy tutaj jakie zdarzenie ma wyzwalać naszą funkcję. W tym artykule wykorzystam funkcję z wyzwalaczem HTTP, dzięki czemu naszej funkcji zostanie przydzielony adres URL, którego odpytanie spowoduje wykonanie naszej funkcji.
- Runtime – środowisko uruchomieniowe naszej funkcji. Użyjemy tutaj Node.js 8, który pod spodem wykorzystuje minimalistyczną wersję frameworka Express.js do obsługi requestów HTTP.
- Source Code – określamy w jaki sposób chcemy wgrać nasz kod do Cloud Functions. Możemy to zrobić poprzez upload archiwum z naszym kodem, bądź skorzystać z inline edytora. Zauważ, że w przykładzie nasza funkcja jest eksportowana z nazwą “helloWorld”
- Function to execute – w tym polu podajemy właśnie nazwę funkcji, która jest zadeklarowana jako ta do obsłużenia requestu HTTP. Musimy tutaj więc podać wartość, która w kodzie zadeklarowaliśmy jako exports.helloWorld
Ponad to w opcjach zaawansowanych mamy możliwość skonfigurowania dodatkowych parametrów takich jak: timeout, zmienny środowiskowe, dostęp do wewnętrznego VPC czy maksymalną ilość instancji funkcji.
Tak jak wspominałem wcześniej nie będziemy tworzyć CF w ten sposób, jednak zachęcam w ramach testów do uruchomienia funkcji typu hello world i próby jej wywołania za pomocą wygenerowanego adresu URL.
Konfiguracja CLI gcloud
Aby w sposób bardziej efektywny wdrażać nasz kod do Cloud Functions potrzebne będzie nam zainstalowanie i skonfigurowanie CLI gcloud. W tym celu musimy pobrać oraz zainstalować SDK dostarczona przez platformę GCP, link tutaj Gdy nasz CLI jest już zainstalowany możemy spróbować się za jego pomocą autentykować do naszego konta GCP. W tym celu w naszej konsoli wpisujemy
gcloud auth login
Komenda powinna otworzyć okno przeglądarki, które poprzeporwadzi nas przez oAuthowy proces logowania do naszego konta w GCP. Po poprawnej autoryzacji jesteśmy w stanie dostać się do naszych zasobów z poziomu linii poleceń. Przykładowo, poniższa komenda powinna wylistować wszystkie nasze projekty utworzone w GCP m.in. ten, który stworzyliśmy na potrzeby Cloud Functions.
gcloud project list
Ostatnim krokiem będzie konfiguracji domyślnego projektu w ramach, którego będziemy się poruszać używając wiersza poleceń. Dzięki temu w późniejszym czasie gdy będziemy wdrażać nasze funkcję nie będziemy musieli każdorazowo deklarować w jakim projekcie mają one zostać zainstalowane.
gcloud config set project cloud-box-functions-demo
Instalacja funkcji w Cloud Functions
Gdy nasz wiersz poleceń jest już gotowy do pracy możemy przystąpić do próby instalacji kodu naszej funkcji. Na potrzeby tego artykułu przygotowałem przykładowy kawałek kodu, który prezentuje w prosty sposób jak nasza funkcja w usłudze CF potrafi obsługiwać zapytania HTTP. Link do repozytorium z kodem
W repozytorium z kodem znajdziesz prostą aplikację Node.js z dwoma plikami JS. W pliku index.js znajduje się przykład funkcji w czystym JS, który potrafi obsłużyć żądanie HTTP rozpoznając również jaka metoda HTTP został wykonana. W pliku express-index.js znajduję się ta sama funkcja, tylko w tym przypadku, do obsługi requestów wykorzystany został framework Express.js. Wykorzystanie tej biblioteki w znaczącym stopniu ułatwia pisanie funkcji tworzących REST API. Mamy bowiem możliwość w przejrzysty sposób zdefiniowania dedykowanej obsługi dla każdego specyficznego żądania, czy to na podstawie parametrów URI, czy metody HTTP. Dzięki temu nasz kod nie będzie drabinką ifów bądź litanią wyrażenia switch. Zachęcam do przetestowania lokalnie obu wariantów. Aby uruchomić lokalnie ów funkcje należy po pobraniu jej wykonać dwie poniższe komendy
npm install
npm run watch
Aplikacja zostanie uruchomiona lokalnie na porcie 8080
Gdy zapoznaliśmy się już z załączonym przykładem funkcji czas na klucz programu, czyli instalacje kodu w Cloud Functions. Wykonanie poniższej komendy w głównym katalogu z naszą funkcją spowoduje jej wdrożenie do platformy GCP. Parameter cloudFunctionDemo jest to nazwa funkcji, która eksportujemy w kodzie jako nasz entrypoint. Flaga -allow-unauthenticated sprawi, że funkcja będzie dostępna publicznie bez wymogu autoryzacji.
gcloud functions deploy cloudFunctionDemo --runtime nodejs8 --trigger-http --allow-unauthenticated
Po chwili oczekiwania nasza funkcja powinna zostać utworzona a w konsoli powinniśmy dostać na zwrotce jej metadane wraz z adresem url, który będzie jej wyzwalaczem. Po powrocie do przeglądarkowej konsoli GCP w zakładce Cloud Functions nasza funkcja również powinna być już widoczna.
Teraz możemy już wykonać finalny test i spróbować wywołać naszą funkcję poprzez przypisany jej adres URL. Adres ten możesz zawsze znaleźć wchodząc na szczegóły w funkcji i przechodząc na zakładkę Triggers
Przechodzimy ponownie do naszego klienta REST, w moim przypadku jest to Postman i wklejamy powyższy adres, próbując wykonać na nim metoda GET oraz POST.
Jeśli wszystko poszło zgodnie z planem, powinniśmy uzyskać ten sam efekt, który wcześniej osiągnęliśmy uruchamiając funkcję lokalnie. Spróbuj w tym momencie kilkukrotnie odpytać dany endpoint, po to aby dostarczyć danych do metryk i logów.
Na koniec jeszcze na powyższym zdjęciu zamieściłem kilka rzeczy i miejsc, na które warto zwrócić informację będąc na ekranie szczegółów funkcji.
- View Logs – przycisk przeniesie nas do usługi, w której będziemy mogli przejrzeć logi naszej funkcje. Wcześniej usługa ta zwała się Stackdriverem ale widać, że Google odchodzi od tej nazwy.
- Wersja funkcji – wszystkie Cloud Functions są wersjonowane. Każdy kolejny deploy funkcji podbija jej wersje.
- Na zaznaczonych wykresach mamy możliwość podejrzenia danych historycznych takich jak ilości wywołań funkcji, czas wykonania funkcji, czy też ilość wykorzystanej pamięci. Są to niezbędne dane do analizy, mogące pomóc w podniesieniu wydajności naszych rozwiązań.
Podsumowanie
To by było na tyle jeśli chodzi o wstęp do Cloud Functions. Mam nadzieję, że informacje znalezione w obu częściach tego artykułu pomogły Ci w rozpoczęciu swojej przygody z Serverless na platformie GCP. Jeśli wpis ten spodobał CI się koniecznie zapisz się na newsletter, aby w przyszłości być na bieżąco z kolejnymi artykułami 🙂