środa, 21 kwietnia 2010

Google Application Engine



Dziś będzie o rzetelności.

WYGLĄDA OBIECUJĄCO

Chmura Google - GAE ogólnie prezentuje się świetnie. Za darmo (do pewnych limitów) dostajemy platformę, która jest w stanie udźwignąć tysiące transakcji na sekundę oraz przechować dla nas terabajty danych w nierelacyjnej bazie BigTable. Do tego dostęp do wielu usług google takich jak bezpieczeństwo, składowanie obrazków, pobieranie zawartości stron poprzez ichni cache, potężny memcache itp.

Programować możemy sobie w Pythonie albo w Javie (okrojonej wersji, bez części klas standardowych i z zakazem korzystania z pewnych bibliotek).

Ogólne założenie jest takie: programiści (i konsultanci;) w większości nie potrafią konfigurować skalowalnych środowisk ani pisać skalowalnych aplikacji, dlatego dostarczmy im platformę, która zajmie się tym problemem w sposób transparentny. Czyli mamy podejście odwrotne do Java EE. Zajmij się problemem biznesowym a chmura zajmie się skalowaniem. Kierunek wydaje się słuszny.

Zatem zaczynamy zabawę...
Na dzień dobry krótka, oficjalna prezentacja z głównej strony jak to fajnie i szybko klepie się aplikacje i odpala je w kosmos: http://www.youtube.com/watch?v=P3GT4-m_6RQ
Trzeba przyznać, że plugin do Eclipse jest wzorowy: prosty w obsłudze (3 sugestywne buttony), działa oraz zapewnia wszystko:
- lokalny server emulujący chmurę i jej zasoby (bazę)
- narzędzie automatycznie "wzbogacające" bytecode klas encji na potrzeby ichniej "implementacji" JPA
- narzędzie wystrzeliwujące aplikację w kosmos
- prosty kreator, który generuje cały ten kosmodrom
(nie odważyłem się zmawenizować wygenerowanego projektu, bo to zwykle tydzień w plecy a na koniec może się okazać, że tracimy hotdeploy)



WTF?

Ale, ale... akcja filmu rozkręca się z czasem...
Jedna z największych firm programistycznych na ziemi pokazuje jak tworzyć kod w... Java Server Pages. Patrzcie uważnie i uczcie się: logika i dostęp do danych w... scriptletach (sic!).

Oczywiście duzi chłopcy wiedzą, ze scriptlety są depricated. A nóż widelec tą scenę zobaczy jakieś małe dziecko i będzie później tak programować jak dorośnie?!? Później znowu przeczytamy w gazecie o tragedii jaka rozegrała się w jakimś spokojnym projekcie. Gdzie byli rodzice?!?

Hmmm dziwne, dziwne... no ale nie czepiajmy się szczegółów, to przecież tylko taki przykład. Przecież zawsze możemy zaprojektować sobie eleganckie warstwy i całość oprzeć o sprawdzony framework.



BOLESNE OGRANICZENIA

Niestety tak jak wspomniałem na początku JVM ma ograniczenia i nie wszystko działa. Seam co prawda daje się uruchomić po zastosowaniu 15 speszyl haków, ale wszyscy twierdzą, że nie warto ryzykować. Na szczęście stary, dobry Spring oficjalnie działa. Wielu dzielnych blogerów publikuje hello worldy i tutoriale jak to poskładać. Wygląda na to, że jedni kopiują od drugich;)

Ba, nawet 2 książki o GAE preferują Springa i pokazują jak go skonfigurować. Hmmm ciekawe dlaczego omawiają tylko servlecik Spring MVC i dyplomatycznie nie poruszają bardziej zaawansowanych zagdanień...?

Niestety, jednak nie działa do końca!
Przykładowo gdy użyjemy technik Aspektowych i przeplatania w czasie uruchomienia to mamy dziwne błędy ClassNotFound. Lokalnie działa, a na chmurze już nie.
Co implikuje, że możemy zapomnieć o aspektowej, eleganckiej obsłudze bezpieczeństwa i transakcji.
Więc po co nam Spring? Tylko do wstrzykiwania? To bez sensu.



UWAGA NA PERSYSTENCJĘ

Nieważne, bez Springa można żyć, idźmy dalej... Nierelacyjna baza BigTable została przez Google przykryta interfejsem JDO albo JPA (do wyboru) więc czujemy się jak w domu.
Nie do końca... specyfikacja ma szereg ograniczeń wynikających z architektury rozwiązania BigTable - chodzi o rozpraszanie struktur danych na różne maszyny po stronie chmury.

Drobny szczególik wspomniany jedynie w dokumentacji jest taki, ze agregaty encji są grupowane w rodziny. Przykładowo jeżeli mamy encję Zamówienie, która ma w sobie listę ZamówionychProduktów to jest to rodzina. Co z tego wynika?

Encja może należeć jedynie do jednej rodziny.
Implikacja: Jeżeli mamy encje Zamówienie i Faktura oraz encję Kleint, który musi być podpięty do Zamówienia jak i Faktury to niestety nie ma takiej możliwości. Dziecko może mieć jednego rodzica. Oczywiście można to obejść i w Zamówieniu jak i Fakturze używać obiektów Kluczy do Klienta. Ale wówczas tracimy łatwość programowania i uzależniamy się od API Chmury.

Trzeba pamiętać, że podejście do modelowania danych w nierelacyjnej bazie wymaga innego "nastawienia" - taka natura rozwiązania. Jeżeli nierelacyjnie to może obiektowo? Jednak nie do końca - no to jak?

Osobiście preferuję takie podejście, że Zamówienie czy Faktura ma owszem klucz do Klienta ale ma również niepersystentne pole Klient, które jest ustawiane w niej osobnym zapytaniem (nie jest to duży koszt w bazie BigTable, która jest tak na prawdę wielowymiarową HashMapą). Tego typu szczegóły można hermetyzować z obiektach Repository, które zwracają dane "poskładane" tak aby było wygodnie. OK, jeden problem z głowy.


Transakcja może obejmować tylko operacje na jednej rodzinie.
Czyli jeżeli logika aplikacji chce zapisać zarówno rodzinkę Zamówienie jak i Faktura to będą to 2 osobne transakcje. A co jeżeli w tak zwanym międzyczasie zdarzy się coś przykrego? Ręczna rzeźba i sprzątanie:)
Poza tym, jak wspomniałem, aspektowe transakcje Springa nie działają, więc brudzimy kod biznesowy kodem API transakcji JPA.


Datanucleus - "implementacja" JPA
Oprócz tego, że jest okrojona to dodatkowo zawiera szereg błędów - nie działają nawet niektóre proste przykłady z tutoriali JPA. Na oficjalnej grupie wisi wiele pytań - bez odpowiedzi.



GWÓŹDŹ

Prezentacja
Z frameworków prezentacji testowałem JSF.
1.2 (z Seam) działa.
2.0 działa po zastosowaniu jednego prostego speszyl haka.

Działa w sensie, że się uruchamia. W 2.0 występują pewne problemy z wstrzykiwaniem ManagedBeanów. RichFaces ani IceFaces nie mają wersji dla chmury. Oficjalnie Primefaces częściowo działa. Znowu nie jest to rzetelna i informacja - AJAX ogólnie się sypie.

No i można zapomnieć o uruchamianiu metod z parametrem przy pomocy nowego silnika wyrażeń (el-api w wersji 2.2). Chmura odmawia współpracy z nowymi zdobyczami.

//==============================

Biorąc pod uwagę powyższe ograniczenia:
- brak wygodnego frameworka (w tym wsparcia dla AOP)
- uboga funkcjonalność ORM wymagająca wielu ręcznych operacji
- mentalny model programowania sprzed o ok 10 lat
Mamy znaczny spadek produktywności.

Domyślamy się skąd te JSP, scriptlety i statyczne metody w filmie promocyjnym? Czyżby tylko to działało?
Szkoda tylko, że community i blogosfera zatrzymuje się na poziomie Hello World i nie weryfikuje nieco bardziej dogłębnie i rzetelnie.

Na zakończenie dodam, że zupełnie inne założenia przy budowie chmury przyjął Amazon. Dostajemy sprzęt i system operacyjny. Nikt nie narzuca nam dodatkowych bytów zbudowanych nad sprzętem i nie wchodzi nam z butami w nasz wypracowany latami i sprawdzony model programowania. I co najważniejsze - wszystko działa:)

14 komentarzy:

KosciaK pisze...

Nawet jeśli różniaste (duże) Javowe frameworki by na GAE działały to pojawi się kolejny problem - kosztowny zimny start aplikacji. Te wszystkie biblioteki muszą zostać załadowane, pożerając czas potrzebny na obsłużenie żądania oraz czas procesora. Im mniejszy ruch w aplikacji tym mocniej będzie boleć.

Irek Matysiewicz pisze...

Czas startu pliku WAR jest zwykle i tak znikomy nawet z 10 frameworkami w porównaniu z czasem startu serwera jak JBoss.
Jeśli ci zależy na szybkim starcie przede wszystkim używaj "małych" serwerów jak Tomcat czy Jetty. Opasłe krowy typu JBoss są tylko do największych aplikacji dla największych klientów.

Sławek Sobótka pisze...

Start na GAE jest generalnie bardzo długi - chmura "rozkłada" sobie aplikację w sobie. Czasem nawet 5 minut.

Mało tego, nieużywana aplikacja "zamiera" i request, który ją budzi trwa niemiłosiernie długo. Hehe są firemki, które za drobną miesięczną opłatą niedopuszczaną do "zamarcia" (pewnie "pingują" jakąś stronkę)

Marek Dominiak pisze...

Jakiś czas temu zastanawiałem się czy pisać coś na appEngine ale po wielu probóbach uruchomienia JSF 1.2 z seamem dałem sobie spokój. Tak jak napisał Sławek trzeba użyć 1000 hacków żeby to się poskładało. To samo z JPA, ograniczenia (o zgrozo JPA w wersji 1.0 już i tak jest na maksa ograniczone)

Ja doszedłem do wniosku że albo trzeba się nauczyć wykorzystywać GWT i Guice albo zapłacić za normalny hosting z zainstalowaym Linuksem gdzie mogę sobie postawić wszystko co chcę i bez takich ograniczeń.

Wujaszek nie lubi konkurencyjnych frameworków więc mimo że jest bardzo dużo votów na to aby obsługa Richfaces działała to i tak się wujaszkowinioe spieszy (a nuż może się nauczą słuszniejszej technologii).

s

KosciaK pisze...

Teoretycznie można by próbować ustawić cron job (albo taskami to zrobić) by cały czas utrzymywać aplikację w ruchu. Ale to chmura, więc nie ma pewności czy kolejny request nie trafi na jakąś nową maszynę. Już nie wspominając o zużywaniu w ten sposób zasobów.
Big Table też może być sporym problemem. Sporo z tego co się wie o tworzeniu schematu bazy trzeba wyrzucić do kosza bo okazuje się bardzo niewydajne.
Niestety GAE nie do wszystkiego się nadaje.
Swoją drogą gdzieś widziałem jakieś porównanie Java vs Python, ciekawe czy są jakieś znaczące różnice wydajności

Anonimowy pisze...

Bardzo ciekawy wpis - dobrze oddaje to, jak na chwilę obecną wygląda GAE. Ja próbowałem odpalić Grailsy na GAEJ. Wyglądało to tak, że musiałem hackować źródła Grailsów, pluginów app-engine, acegi i gorm-jpa. Udało mi się nawet uruchomić prostą aplikację z logowaniem i zarządzaniem użytkownikami ale po pewnym czasie w ogóle nie dało się aplikacji odpalić - uruchamiała się dłużej niż 30 s... Dałem sobie spokój z Grailsami i przerzuciłem się na Spring MVC + JSP + JDO + scheduler pingujący aplikację żeby nie zdechła :) Takie połączenie nawet jako tako działa... Ponoć Play Framework dobrze sobie radzi na GAEJ. Generalnie wychodzi chyba na to, że lepiej napisać aplikację w RoR, Grailsach, czy Django a wydajnością martwić się, jak faktycznie będą z nią problemy :)

Sławek Sobótka pisze...

Osobiście obawiam się wynalazków typu Play, ponieważ jak napisał (mniej więcej, cytat z pamięci) kiedyś jeden sędziwy programista:

"Ograniczeni umysłowo twórcy 'frameworków' twierdzą, że rozwiąże on 95% problemów. Po wstępnych oględzinach uznajesz, że jest to 50%. Jak zaczynasz używać w nietrywialnych przypadkach niebędących Hello World i zagłębiać się to wychodzi jedynie 5%. Pozostałe 95% to same problemy wynikające z wspomnianych ograniczeń"


Co do wydajności i chmury to masz rację. Ale co jeżeli chmura jest elementem wizerunku produktu oraz filarem jego kampanii marketingowej?:P
Nie będę tego dalej rozwijał, ale są przypadki gdzie na prawdę jest to racjonalny pomysł.

Piotr Gabryanczyk pisze...
Ten komentarz został usunięty przez autora.
Piotr Gabryanczyk pisze...

Rzeczywiscie, jesli przyzwyczailes sie do ciezkich bibliotek jak spring, jsf, hibernate, etc, to trudno jest przejsc na appengine - odradzam.

Natomiast jesli cenisz prostote to lekkie srodowisko jsp+guice+jdo na appengine da ci spora poprawe wydajnosci pracy.

Od 9 miesiecy w mojej firmie uzywamy appengine do hostowania webservice-ow i prostych aplikacji webowych. Do tego nadaje sie genialnie.

Gdy jestesmy na wakacjach nikt nie musi sie martwic: Czy padl nam tomcat? A moze mysql nie ma juz miejsca na dysku? Czy ktos wogole monitoruje aplikacje? Czy backup na pewno sie wykonal? A jak padnie serwer to jak go skonfigurowac od nowa i ile to zajmie czasu? Te wszystkie problemy zalatwia appengine. Nawet jak padnie, co jeszcze mu sie zdarza, to tez nas nie martwi bo chlopaki z Google raz dwa rozwiazuja problem.

Swietnie rozwiazany jest deployment: wrzucasz nowa wersje na appengine, testujesz w srodowisku docelowym, a potem tylko przelaczasz pstryczek i ciach juz jest na produkcji. Nie dziala? No coz przelaczasz spowrotem i jestes na starej wersji. Dla nas jest to kluczowe, bo pozwala uniknac wpadek na produkcji, ktore kosztuja wiele w relacji z klientem. Pozwala tez czasem agresywnie wrzucac nowe rzeczy na produkcje bez strachu, ze jak nie zadzialaja to ciezko bedzie sie wycofac.

Amazon swietnie sie sprawdza tam gdzie chcesz miec kontrole nad infrastruktura i uzywamy go do hostowania serwera deweloperskiego - wiki/ci/bugtracking etc.

Gdy dostarczam rozwiazanie klientowi nie chce zeby placil on za kofiguracje serwerow - wole jesli wyda swoje pieniadze na to co dla niego wazne, czyli nowa funkcjonalnosc.

Oczywiscie appengine to jeszcze nowy produkt i nie jest wolny od wad, ale wg. mnie kierunek ktory reprezentuje to przyszlosc hostingu aplikacji.

Sławek Sobótka pisze...

Generalnie zgadzam się, że kierunek jest dobry. Jestem wręcz przekonany, że z czasem stanie się to standardem. Już teraz średnie i większe firmy softwarowe, które jednocześnie hostują swe produkty stawiają swoje własne chmury. Z czasem na pewno chmury zaczną dostarczać środowisko developerskie wspierające konkretne modele programistyczne (modele w sensie mentalnym). Gdy tylko to nastąpi, wówczas ma pewno będę jednym z pierwszych "pasażerów":)


Ale póki co w szczegółach tkwi jak wiadomo sam uber-diałbeł;)

Czy spring jest ciężki? Hmmm podobno to J2EE było ciężkie i smutne, co było inspiracją do powstania lekkiego Springa. Ale to kwestia subiektywnego wyważenie "ciężaru" i konsekwencji, zysków i strat na różnych poziomach...

Sam spring jest bogatą biblioteką (raczej nie frameworkiem) rozwiązań wieli żmudnych problemów, takich jak bezpieczeństwo czy transakcje.

Wystrzykiwanie zależności to tylko środek do osiągnięcia odwrócenia kontroli na takim poziomie aby móc osiągnąć aspektowe konstrukty. Wstrzykiwanie samo w sobie nie niesie dużej wartości w "zwykłych" projektach, gdzie architektura nie musi być na tyle giętka aby była potrzeba utrzymywania wysokiego poziomu abstrakcji wymiennych "klocków". Tak więc sam Juice to dla mnie mało. Bez różnych ficzerów można żyć, pytanie tylko jakim kosztem.

Co do problemów z konfiguracją to kwestia doświadczenia i skilla. A na przykład szybkie podmiany można realizować w sposób jaki sam Martin Fowler lansuje w swych projektach, czyli zwykłe przełączenie IP.

Sławek Sobótka pisze...

Zapomniałem odnieść się do JSP na szczycie stosu. Osobiście przerabiałem to już 6 lat temu...

Moja wizja jest taka, że był to kiedyś jakiś tam rozdział w historii. A od tego czasu pojawiło się wiele narzędzi budujących wyższy poziom abstrakcji, przez co drastycznie zwiększających produktywność (która jest tak istotna, co sam podkreślasz na końcu swego posta).

Lasu aka Marek Kozieł pisze...

A na mnie się patrzyliście dziwnie jak pisałem bazę danych na csv-ach ;P
Ale widzę, że jestem daleko za peletonem w kombinowanych rozwiązaniach.

Jeśli mówicie o kierunku/tendencji to przydało by się podać oczekiwany czas takowego zachowania.

GAE ma racje bytu do prostych zastosowań, na następne kilka lat jest idealne. Wadą tego rozwiązania jest fakt, że nic specjalnie złożonego na nim nie zrobimy.
Google zdobyło rynek dzięki funkcjonalności, szybko dostarczane aplikacje mają racje bytu tylko do czasu pokazania się na rynku czegoś porządnego co wymiecie resztę konkurencji.

A rynek się zmienia, uważacie, że za kilka lat firmy dalej będą potrzebować rozwiązań od ręki i na kilka miesięcy (a przynajmniej te poważniejsze)?

Bolo pisze...

Ostatnio sam zastanawialem sie nad uzyciem GAE, ale skuteczenie zniechecilo mnie ograniczenie warstwy 'trwalosci' do BigTable - skladu danych (a nie bazy danych) zapewniajacego wylaczenie atomowosc transakcji. To nie jest cofniecie sie o 10 a o 20 lub wiecej lat do tylu. Z mojego punktu widzenia oznacza to, ze na GAE mozna rozwijac tylko aplikacje, w ktorych dane nie maja wartosci. Tylko po co w takim razie cos takiego pisac ?

Sławek Sobótka pisze...

@Bolo: pewne klasy problemów niebiznesowych jak najbardziej zadowolą się małowartościowymi danymi: np komentarze na jutubie i innych podobnych sprawach.

Wydaje mi się, że właśnie po to Google udostępnił tego typu platformę - aby stymulować ludzi do realizacji swoich pomysłów webowych. Jak jeden na 10 000 pomysł wypali (a'la fejsbuk) to się wykupi chłopaków wraz z rodziną i inwestycja się zawsze zwróci:)