Google App Engine, del 4: Begränsningar och hur man tar sig runt dem

Att använda Google App Engine har stora fördelar, men det finns också vissa begränsningar med plattformen som det är viktigt att känna till. Det är absolut inte alla applikationer som kan köras med fördel på Google App Engine. Google jobbar på att fixa till de flesta av dessa begränsningar och med tiden så kommer man säkert att göra så, men det hjälper inte så mycket just nu. I denna fjärde artikel om Google App Engine så tar vi en titt på vilka begränsningar som finns och hur man kan komma runt dem vissa av dem.

Tidigare artiklar om Google App Engine har gett en översikt av vad Google App Engine är, hur man kan använda Google App Engine för att bygga sitt eget CDN och hur man utvecklar för Google App Engine.

UPPDATERING: Vissa av begräsningarna som jag beskriver i detta inlägg har nu tagits bort av Google, läs Google App Engine – nu med Java och bakgrundsprocesser för mer detaljer.

Endast Python

Om du inte behärskar Python så är det bara att bita i det sura äpplet och lära sig. Det är inte ett svårt språk att lära sig om man har lite programmeringskunskaper. Samma sak gäller Django, som är ett Pythonramverk som underlättar väldigt mycket när man utvecklar webbapplikationer. Innan jag började med Google App Engine så hade jag inte skrivit en rad Python och efter ett par dagars koncentration och kaffekonsumtion så var jag helt inne på Python, Django och Google App Engine.

Många tredjeparts python bibliotek fungerar perfekt på Google App Engine, men vissa begränsningar finns. Endast bibliotek som är 100% Python kan användas, så om ett bibliotek har C-kod så kan det inte användas på Google App Engine. Om ett bibliotek har kod som gör HTTP anrop eller liknande så kommer det inte heller att fungera på Google App Engine. Alla HTTP requests måste gå via Google App Engines eget URL Fetch API.

Skillnader mellan den lokala utvecklingsmiljön och produktionsmiljön

En av fördelarna med Google App Engine är att det finns en lokal webbserver som till stora delar efterliknar hur Google App Engines produktionsmiljö fungerar. Detta gör det lätt att utveckla en applikation lokalt för att sedan produktionssätta den på Google App Engine. Som utvecklare så är det viktigt att vara uppmärksam på de skillnader som finns på att köra en applikation på den lokala servern och i produktionsmiljö, det är inte kul att ha spenderat tid på att utveckla kod som helt enkelt inte fungerar när den väl är produktionssatt.

Den största skillnaden mellan att köra en applikation lokalt och i produktionsmiljö är att de anrop som görs till tredjepart ser olika ut. Om man har en applikation som använder Delicious API så kommer den att fungera bra när man kör från sin lokala server, men den kommer inte att fungera alls i produktionsmiljö. Anledningen är helt enkelt att Delicious har blockerat anrop från Google App Engines IP-addresser. Samma sak sker med anrop till Twitters API (även om Twitter sägs ha fixat det nu) pga vissa HTTP headers som Google App Engine sätter (och som man inte kan ändra själv). För att undvika dessa problem så är det generella rådet givetvis att testa i produktionsmiljö ofta för att vara säker att man inte har problem.

Datastore

Google App Engines Datastore har några begränsningar som kommer av att det är en distribuerad databas. Den tydligaste begränsningen är att det inte finns någon “OR” operator i GQL (Datastores motsvarighet till SQL), men det är inte alltför svårt att hantera när man kodar. En mer irriterande begränsning är att man inte kan skapa en ny entity (dvs dataobjekt) i Datastore via Google App Engine Dashboard om det inte redan finns en entity av den typen, samt att man det finns en märkbar tidsfördröjning på vad som man kan se i Datastore i sin Dashboard och vad som verkligen finns i Datastore. Detta gör att det kan vara svårt att ha kontroll på vilken data som finns i Datastore i ett givet ögonblick, vilket försvårar debuggande av applikationer.

Inga bakgrundsprocesser

En av de stora begränsningarna med med Google App Engine är att det inte finns något annat sätt att starta en process än via ett HTTP anrop, hela plattformen är endast avsedd för webbapplikationer. Det finns ingen typ av schemalagda processer (tex cron jobs) eller triggers/hooks man kan använda sig av för att starta en process när ett speciellt event inträffar. Nästan alla webbapplikationer behöver någon sorts bakgrundsprocess för att fungera korrekt – det kan handla om att rensa upp gammal data, att konsolidera statistik eller att inhämta data från RSS feeds en gång i timmen.

Det enklaste sättet att komma runt denna begränsning är att sätta upp ett cron job på en annan server som kallar en URL i din webbapplikation på Google App Engine. Om man har många besökare och den process som man behöver schemalägga så kan man också haka på ett användaranrop, tex om en användare vill logga in till din applikation så kan loginprocessen också importera data från ett RSS feed. Detta kan göra användarupplevelsen slö och det finns ingen garanti att användare kommer till din applikation vid de tidpunkter då din applikation behöver exekvera sina processer.

Oavsett vilken lösning man använder så stöter man snabbt på nästa begränsning i Google App Engine, nämligen att endast kortvariga processer är tillåtna.

Endast kortavariga processer

Något jag har fått lära mig den hårda vägen är att Google App Engine är byggd endast för att hantera webbapplikationer där en användare gör ett anrop och får tillbaka ett snabbt svar. Det finns inget stöd för att en process kan köra en längre tid, för tillfället så verkar begränsningen vara ca 9 sekunder per process. Efter denna tid så kastas ett exception och processen avslutas. Inte nog med det, även om man inte är i närheten att använda de CPU cyckler man är tilldelad så kan man snabbt använda för mycket resurser med långvariga processer. Då låses ens Google App Engine applikation till nästa 24 timmars period startar.

Detta är verkligen en seriös begränsing i Google App Engine som det är svårt att komma runt. Om man behöver tunga bakgrundsprocesser så rekommenderas istället Amazon EC2 eller någon annan liknande lösning. För att hantera (inte komma runt) begränsningen så måste man hantera exceptions på ett snyggt sätt, använda try-finally och transactions.

Mer om detta kan ni hitta på William Vambenepe’s mycket informativa blogginlägg Emulating a long-running process (and a scheduler) in Google App Engine. Han har några tips på hur man kan försöka ta sig förbi denna begränsning, även om det inte är att rekommendera eftersom man riskerar att applikationen låses.

Fler begränsningar

Det finns ännu fler begränsningar, läs Google App Engine: The good, the bad, and the ugly? för en mer detaljerad lista (en del av de begränsningar som nämns där har redan åtgärdats av Google).

Slutsatsen är att man måste ha god koll på vilka begränsningar som Google App Engine har innan man investerar tid och ork på att utveckla en applikation. Om begränsningarna inte är ett problem så finns det oerhört mycket att vinna på att använda Google App Engine.

The End

Detta är den fjärde och sista delen i denna artikelserie om Google App Engine. Förhoppningsvis har den varit användbar och fått några av er att börja utveckla på Google App Engine. Kontakta mig gärna när ni har något att visa, det skulle vara kul att skriva lite mer om svenska användningar av Google App Engine.