W dzisiejszym wpisie na warsztaty weźmiemy sobie jedną z Serverlessowych usług ze stajni Google Cloud Platform. Mowa tutaj o usłudze, która jest określana jako odpowiednik AWS Lambdy czyli Cloud Functions. Wpis ten zostanie podzielony na dwie części. Tutaj w pierwszej części tego wpisu przybliżymy sobie charakterystykę usługi oraz najważniejsze informację z nią związane. Druga część będzie tą bardziej praktyczną, gdzie pokaże Wam jak uruchomić kod naszej funkcji w Cloud Functions.

Czym jest Cloud Functions ?  

Cloud Functions jest to serverlessowa usługa chmury Google idealnie wpisująca się w model FaaS (Function as a Service), na co wskazuje już sama jej nazwa.  Czym charakteryzuje się usługa serverless opisywałem już w tym artykule, zachęcam do zapoznania się z nim. W skrócie chodzi o to, że mamy możliwość wykonania kodu napisanej przez nas funkcji w środowisku chmurowy nie potrzebując do tego żadnej infrastruktury, czytaj serwera. Piszemy kod, wrzucamy go do chmury i nasza funkcja jest gotowa do wywołania. Jak wygląda wywołanie funkcji ? Tutaj pojawia się kilka opcji. Wywołania Cloud Functions bazują na zdarzeniach. Oznacza to, że sami określamy jaki event będzie powodował wykonanie kodu naszej funkcji. Takim eventem może być np. wykonanie żądania HTTP, pojawianie się nowego pliku na naszym storage, bądź np. cyklicznie odpalany scheduler. Zgodnie z ideą Serverless płacimy tutaj tylko i wyłącznie za czas gdy nasza funkcja jest uruchomiona – wywołana. Gdy nasza funkcja się nie wykonuje, nie zostają naliczane żadne dodatkowe opłaty.

Jak działają Cloud Functions ? 

 

Aby najlepiej to zobrazować posłużę się poniższym.

cloud function diagram

Powiedzieliśmy sobie, że Cloud Functions wywoływane są poprzez zdarzenia. Najczęściej emiterami takich zdarzeń jest nasze środowisko chmurowe czyli inne usługi z których korzystamy. Częstym use-casem jest np. zdarzenie pojawiania się nowego pliku w Cloud Storage. Prześmiewny przykład, który pojawia się na wielu prezentacjach i szkoleniach, mimo wszystko jest to jedno z najczęstszych realnych zastosowań :). Gdy nowy plik pojawi się na storage, zostanie wyemitowane zdarzenie, które wywoła i przekaże dane związane z eventem naszej funkcji, aby ta podjęła działanie. Przykładowo, użytkownik naszego systemu robi upload swojego zdjęcia profilowego. Zdjęcie to trafia do Cloud Storage a nasza funkcja ma za zadanie skompresować owe zdjęcie i zapisać je być może nawet w kilku rozdzielczościach i formatach, które później będą wykorzystywane w naszym systemie. Funkcja w trakcie działania ma możliwość wywołania innych serwisów. Mogą to być inne usługi chmurowe albo API usług zewnętrznych spoza infrastruktury clouda. 

Cloud Functions od podszewki 

Z racji tego, że Cloud Functions pracują w myśla paradygmatu Serverless, uruchamiając w nich kod nie martwimy się o infrastrukturę czyli o konfigurację serwerów oraz sieci. Za to wszystko odpowiedzialny jest dostawca chmury. Naszym zadaniem jest skupić się nad logiką naszej funkcji, tak aby rozwiązywała on problemy biznesowe. Skoro nie musimy martwić się o infrastrukturę oznacza to również, że z naszych pleców znikają zmartwienia związane z dostępnością czy skalowaniem naszego rozwiązania. Aby dostawca mógł zarządzać i automatycznie skalować nasze funkcję muszą być one bezstanowe. Nie powinniśmy zapisywać w pamięci jakichkolwiek danych w celu wykorzystania ich przy kolejnym wywołaniu funkcji. 

Pojawienie się zdarzenia sprawia, że inicjowana jest instancja naszej funkcji. Każde zdarzenie może spowodować zainicjowanie zupełnie nowej instancji. Dzieje się tak dlatego, że każda z instancji funkcji może obsługiwać tylko jedno żądanie w czasie rzeczywistym. Oznacza to, że jeśli nasz funckcja został wywołana raz i ciągle się procesuje, to w momencie gdy pojawi się drugie żądanie, GCP uruchomi drugą instancję funkcji aby ta obsłużyła kolejne żądanie równolegle. Tak właśnie działa mechanizm skalowanie Cloud Functions. Dopiero gdy funkcja skończy swoją pracę jest na pewien nieokreślony czas uśpiona i ma możliwość podjęcia kolejnego żądania jeśli takie zaszło. Jeśli nie, to po pewnym czasie instancja funkcji zostanie ubita a kolejne zdarzenie spowoduje ponowne zainicjowanie instancji. 


Cold Start

Możecie się zastanawiać po co ten mechanizm “usypiania” instancji i czemu za każdym razem nie zostaje uruchomiony zupełnie nowy byt ? Tutaj należałoby wprowadzić pojęcie tzw. cold startu. Temat zasługuje na odrębny wpis, ale pokrótce wyjaśnię. Powiedzieliśmy sobie, że aby kod naszej funkcji został wykonany, GCP musi uruchomić instancję naszej funkcji. Na tą czynność składają się kilka operacji m.in. przydzielenie zasobów, uruchomienie kontenera funkcji oraz wgranie naszego kodu wraz z środowiskiem uruchomieniowym. Dopiero po tych operacjach nasz kod będzie gotowy do działania. Często jest tak, że zainicjowanie funkcji trwa dłużej niż wykonanie naszego kodu. Właśnie stąd wzięło się pojęcie zimnego startu. Dlatego właśnie provider nie ubija instancji funkcji gdy tylko ta kończy swoje działanie, a jedynie na pewien czas ją usypia. Dzięki temu kolejne wywołanie funkcji ma szansę trafić na uśpioną instancję, która nie wymaga nowej inicjalizacji, przez co unikamy ponownego wystąpienia cold startu.

cloud functions - cold start

W jakich językach można pisać Cloud Functions ?

Na dzień pisania tego artykułu Google Functions umożliwia wgrywanie funkcji napisanych w poniższych technologiach 

  • Node.js 8 (wersja językowa 8.15.0)
  • Node.js 10 w fazie Beta (wersja językowa 10.16.2)
  • Python (wersja językowa 3.7.6)
  • Go 1.11 (wersja językowa 1.11.6)
  • Go 1.13 (wersja językowa 1.13.1)

Jest jeszcze wersja Node.js 6 jednak jest oznacza już jako deprecated i zostanie całkowicie zablokowana z dniem 04.22.2020 więc nie ma sensu skupiać się nad tym środowiskiem.

Jak widzimy wybór języka i środowiska, które możemy wybrać do pisania naszych funkcji jest dość ubogi w porównaniu z tym co umożliwia nam AWS Lambda. Jeśli z żadną z powyższych technologii nie jesteśmy zaznajomieni powinniśmy zainteresować się innym rozwiązaniem Serverless, które w swym portfolio usług posiada GCP, a mianowicie Cloud Run. Usługa ta umożliwia nam uruchamianie w modelu Serverless tym razem nie funkcji a kontenerów z naszą aplikacją. Już niedługo na blogu pojawi się wpis na temat tego rozwiązania.


Rodzaje Cloud Functions 

Zasadniczo możemy podzielić Cloud Functions na dwa rodzaje

  • HTTP Functions – funkcje wywoływane w sposób synchroniczny bezpośredni poprzez endpoint HTTP, który automatycznie przypisywany jest do funkcji w momencie jej wdrożenia. W przypadku tego typu funkcji zdarzeniem jest sam request HTTP, więc w kodzie samej funkcji mamy dostęp do wszystkich informacji związanych z tym żądaniem np. metoda HTTP, nagłówki, parametry requestu. Jesteśmy również w stanie zbudować dowolną odpowiedź HTTP dzięki czemu za pomocą Cloud Function jesteśmy w stanie zbudować pełnoprawny interfejs REST-owy. W drugiej części artykułu przejdziemy sobie krok po kroku przez proces uruchamiania tego typu funkcji.

  • Background functions – funkcje tego typu wywoływane są poprzez zdarzenie generowane przez inne usługi z infrastruktury GCP. Przykład takiej funkcji został przytoczony już wcześniej – ten z nowym plikiem na Cloud Storage. W przypadku takiej funkcji każde zdarzenie będzie niosło ze sobą inny obiekt danych. Obiekt ten będzie zależeć od tego jaka usługa go wyemitowała. Inne dane będzie propagował zdarzenie z Cloud Storage a inne z usługi Pub/Sub

Podsumowanie

To tyle jeśli chodzi o wprowadzenie do Cloud Functions. Przybliżyliśmy sobie tutaj specyfikę tej usługi oraz omówiliśmy podstawowe rzeczy z nią związane. Zapraszam Cię do drugiej części wpisy gdzie krok po kroku pokaże w jaki sposób uruchomić funkcję Serverless w Google Cloud Platform.

Close Menu