Być może trudno to sobie wyobrazić, ale AWS Lambda, która dzisiaj jest niemal synonimem dla paradygmatu Serverless, nie jest prekursorem tego modelu wytwarzania opgrogramowania. Uruchomienie usługi Google App Engine w 2008 roku oznaczało początek nowego trendu, w którym rola programisty kończy się na obsłudze wywołań funkcji zdefiniowanych wewnątrz aplikacji, natomiast za zarządzanie (start, zatrzymanie, przydział zasobów, monitoring, skalowanie, itd.) jest odpowiedzialny jej dostawca.
W momencie, gdy Google udostępniło App Engine odczytywano ten ruch jako odpowiedż na AWS EC2. Nie do końca słusznie, bo AWS Elastic Cloud Computing to klasyczny przykład modelu IAAS, czyli usługi, która polega na zarządzaniu wirutualnymi systemami, które są konigurowane przez użytkowników. W 2007 roku EC2 był prawdziwą rewolucją, bo przysłowiowy Kowalski, który nigdy nie był w serwerowni mógł w przeciągu kilku minut “wyklikać” wirtualną maszynę dostępną w internecie, ze stałym adresem IP i uruchomić na niej cokolwiek. Stąd nazwa Infrastructure As A Service - AWS w imieniu użytkowników EC2 administruje “serwerami”, pilnuje by działały ciągle i bez błędów. Jeżeli chcemy napisać aplikację na przykład w Springu musimy samodzielnie zainstalować na takim systemie Tomcata, bazę danych, skonfigurować uwierzytelnianie i autoryzacj, itd. Trzeba też zadbać o to, by wszystko startowało razem z systemem (np napisać skrypty startowe na linuksie, albo dodać do serwer aplikacji do Usług Windows), bo AWS może w każdej chwili zrestartować naszą wirtualną maszynę. Jeżeli aplikacja ma się skalować i być stale dostępna być może będziemy musieli zreplikować instancję. A więc otrzymujemy eleastyczność, ale żeby ją wykorzystać musimy dysponować wiedzą ekspercką, by móc dostarczyć użytkownikom wydajny i bezpieczny produkt.
Google App Engine idzie krok dalej - nie dość, że nie musimy przejmować się działaniem systemu operacyjnego, to na dodatek z naszych barków spada też problem zarządzania aplikacją, jej skalowania i w dużej mierze jej zabezpieczania. Jeżeli aplikacja wogóle używana w ciągu ostanich 15 minut, zostaje automatycznie zatrzymana. Jednak, gdy przychodzi nowe żądanie, zostaje ponownie uruchomiona. Gdy szybkow wzrasta liczba zapytać, wtedy App Engine może automatycznie wystartować kolejne instancje naszego programu, by zrównoleglić ich obsługę i szybciek odesłać odpowiedź. Jest to tak zwany model PAAS - Platform As A Service.
Takie podejście ma mnóstwo zalet - w modelu IAAS nie musimy mieć doświadczenia z uruchamianiem serwerowni, protokołów sieciowych, albo zestawiania połączeń. W modelu PAAS możemy zapomnieć o administracji systemem operacyjnym, bazą danych a nawet serwerem aplikacji. Ale konsekwencją jest ograniczenie do platformy, którą dostarcza nam operator. W początkach App Engine byliśmy ograniczeni do Pythona w wersji 2.5, krótko potem Servlety Java, a następnie PHP, Go i wreszcie NodeJs. Dostęp do zasobów takich jak system plików jest mocno ograniczony. Nawet jeżeli możem zapisać plik we wskazanym katalogu, nie mamy pewności, że znajdziemy ten plik w kolejnym wywołaniu, bo żądanie od tego samego użytkownika może zostać przekierowane do zupełnie innej instancji. Dlatego Google App Engine od początku był wyposażony w dość bogate API, które pozwalało zapisywać dane w bazie NoSQL albo w cachu, zapisywać pliki binarne, manipulować obrazami, wykonywać zapytania do innych usług itp.
Poniżej podaję krótką charakterystykę wybranych usług dostarczanych w ramach Google App Engine. Na szczegółowy opis przyjdzie jakiś czas. Warto w tym momencie podkreślić, że do określonych limitów można z nich korzystać bezpłatnie, a że limiti są dość wysokie, to App Engine powinno być brane pod uwagę, gdy rozważamy uruchomienie nowej usługi i nie chcemy (przynajmniej na początku) ponosić z tego tytułu kosztów. Oczywiście cały czas mając na uwadze konsekwencje. Pomijając słabą opinię na temat Googla i polityki tej firmy, która często powoduje usuwanie konta bez ostrzeżenia, będzie to na pewno używanie API specyficznego dla App Engine. Jeżeli stwierdzimy, że ta platforma nam nie odpowiada, to migracja na inne rozwiązanie będzie trudniejsza.
Runtime
Działając w modelu PASS Google App Engine określa w jaki sposób żądania wysyłane przez klienta są dostarczane do aplikacji. Na przykład w przypadku Pythona 2.7 jest to WSGI, a Javy Servlet API. Zatem, jeżeli wspomagamy się w pracy frameworkiem, na przykład Springiem albo Django, musi on wspierać wspomniane standardy. Oprócz Pythona i Javy do wyboru mamy jeszcze PHP, NodeJs i GO. Co ciekawe nie jesteśmy na stałe przywiązani do określonego języka. Jeżeli w pewnym momencie zdecydujemy się na przejście z Pythona na NodeJs, oprócz implementacji funkcji w innym języku musimy tylko zmienić plik konfiguracyjny. Co ciekawe dwie wersje obsługujące różne runtimy mogą działać równolegle obok siebie.
Koszt działania aplikacji na platformie App Engine jest rozliczany w godzinach. Każda godzina działania na podstawowej instancji (128 MB RAM, 600 Mhz CPU) kosztuje 5 centów. W ramach bezpłatnego limitu otrzymujemy codziennie 28 godzin do wykorzystania.
Zapisywanie danych
Podstawowym kontenerem do zapisaywania danych jest Cloud Datastore, którego można używać przez API niskopoziomowe albo wysokopoziomowe. W przypadku tego drugiego dla Javy to będzie JPA z ograniczeniami, a Pythona ndb.
Cloud Datastore to dokumentowa baza NoSQL, w której podstawowa jednostka encja odpowiada krotce relacyjnej bazy danych, oczywiście ze wszystkimi różnicami. Encja jest zbiorem par atrybut - wartość. Zarówno całej encji jak i poszczególnym atrybutom można nadawać typ - liczbowy, znakowy, data, tekst, itd. Modyfikacja wartości odbywa się za pomocą API (np wspomnianego JPA czy ndb), a odczyt dodatkowo można realizować przy pomocy GQL - zubożonej wersji SQL dostosowanego do właściwości Cloud Datastore.
Według zapewnień operatora Cloud Datastore jest wysoko dostępna (High Availablity) i skalowalna, w konsekwencji niektóre właściwości znane z tradycyjnych baz SQL są zubożone. Na przykład Cloud Datastore umożliwia przetwarzanie w transakcjach, jednak tylko w określonym zakresie. W ramach bezpłatnego limitu można zapisać 5 GB danych i codziennie wykonać określoną liczbę operacji odczytu i zapisu.
Alternatywą dla Cloud Datastore jest Cloud SQL - serwis zupełnie odrębny od App Engine, przy pomocy którego możemy utworzyć w pełni relacyjną bazę danych i komunikować się z nią w tradycyjnym języku SQL. W odróżnieniu od Cloud Datastore Cloud SQL nie oferuje bezpłatnego limitu.
Do trzymania danych nietrwałych, co może być istotne z uwagi na wydajność naszej aplikacji, używa się serwisu Memcache. Usługa pozwala na szybki zapis i odczyt danych w postaci klucz - wartość. Czas zapisu jest znacząco niższy niż w przypadku Cloud Datastore, jednak w odróżnieniu od tego drugiego, dane z Memcache mogą zostać usunięte w dowolnej chwili. W podstawowej formie można korzystać z Memcache za darmo.
Uwierzytelnianie i autoryzacja
Uwierzytelnienie i autoryzacja to kluczowe zagadnienia w tworzeniu aplikacji internetowej. Bowiem prawie zawsze istnieje grupa użytkowników, którym chcemy pozwolić na więcej i grupa użytkowników, którym wolno mniej. Zarządzanie użytkownikami i uprawnieniami można robić na wiele sposobów i to samo dotyczy Google App Engine, w tej sekcji chciałbym się jednak skupić na konkretnym rozwiązaniu dostępnym w ramach platformy.
Tylko przy pomocy pliku konfiguracyjnego możemy ustawić zasoby, do którym dostęp mają użytkownicy zalogowani na konto Google (uwaga na poleganie na zamkniętym rozwiązaniu - ewentualna migracja w przyszłości może być bardziej utrudniona!) i do których ma dostęp wyłącznie administrator aplikacji. Jest to bardzo wygodne rozwiązanie - razem z platformą dostajemy API, za pomocą którego możemy rozpoznać użytkownika, a wszystkie kwestie związane z określeniem uprawnień i bezpieczeństwa danych przerzucamy na Google. Ma to niebagatelne znaczenie szczególnie w kontekście RODO.
Na zakończenie trzeba podkreślić, że Google App Engine to opcja warta rozważenia w każdym przypadku, a już na pewno wtedy, gdy dopiero rozpoczynamy realizację nowego pomysłu. Dzięki temu, że przyznane limity są dość wysokie umożliwi to obsługę aplikacji w początkowym okresie w zasadzie bez ponoszenia kosztów. Co więcej, jeżeli będzie właściwie zaimplementowana, zgodnie z dobrymi praktykami, możemy się spodziewać, że jej wydajność będzie satysfakcjonująca. Schody rozpoczynają się dopiero, gdy ruch w naszej aplikacji zaczyna rosnąć (czego życzę sobie i każdemu innemu ;)). Co prawda program będzie się skalował, ale razem z tym zaczną rosnąć nasze wydatki, a trzeba zaznaczyć, że usługa poza bezpłatnym limitem jest dość droga. Niebagatelne znaczenie ma też zamknięcie na określone API dostarczone przez platformę i specyfika Google jako dostawcy ze słabym wsparciem technicznym i często nieprzewidywalnym.