"Was ist... ?" - Google App Engine

"Was ist... ?" - Google App Engine

In diesem Beitrag von "Was ist... ?" möchte ich ein wenig auf die Google App Engine eingehen. Ich versuche dabei kaum Vorwissen vorrauszusetzen und auch das Ganze mit kleinen Codebeispielen aufzulockern.

Die App Engine ist ein von Google angebotenes und betriebenes Produkt. Es bietet Entwicklern die Möglichkeit, geschriebenen Code schnell in ein Produktivsystem zu überführen, ohne Aufwand in die Installation und den Betrieb eigner Infrastrukturen zu stecken. In den folgenden Abschnitten wird auf die Schnittstellen, die Integration in den Entwicklungsprozess und einige Features wie das automatische Skalieren bei erhöhter Last, eingegangen.

Schnittstellen

Platform as a Service Produkte (abgekürzt PaaS) - wie die Google App Engine eins ist - bieten seinen Nutzern den Vorteil, keine eigenständige Installation und Konfiguration der Infrastruktur und Diensten - wie z.B. Datenbanken - durchführen zu müssen. Um diese Abstraktion zu ermöglichen, bieten PaaS-Anbieter ihren Nutzern Schnittstellen, über die diese Dienste angesprochen werden können. Diese Abstraktionsschicht ermöglicht den Anbietern, Zusatzfunktionalität wie Skalierbarkeit oder die Verknüpfung mehrerer Dienste (Bsp.: Authentifizierung und Datenbank) anzubieten.

Am Beispiel der Google App Engine bedeutet die Bereitstellung von Schnittstellen, dass sich der Entwickler ein App Engine SDK für seine genutzte Programmiersprache in sein Projekt installiert und gegen dessen Bibliotheken programmiert. Somit ist ein wichtiger Faktor bei der Wahl des richtigen PaaS Anbieters zuallererst, welche Programmiersprache unterstützt wird.

Google App Engine unterstützt Java, Python, PHP und Go (siehe hier). Für den Entwickler bedeutet dies allerdings auch eine Reduzierung der Flexibilität. Anwendungen werden durch die Nutzung solcher SDK sowohl in ihrer Sprachwahl eingeschränkt, als auch wird der spätere Wechsel zu einer eigenen Infrastruktur oder einem anderen Anbieter erschwert. Für Anwendungen, die auf die App Engine ausgelegt sind, gibt es zwar Alternativen - wie z.B. durch AppScale - die ermöglichen, dass App Engine Anwendungen auf die eigene Infrastruktur portiert werden können (siehe hier), doch wie aktuell diese Alternativen gehalten werden in Bezug auf die Weiterentwicklung der App Engine Schnittstellen und ihrer nicht gewährleisteten Existenz in ein paar Jahren bleibt offen. Entwickler, die ihre Anwendungen zukunftssicher halten möchten, müssen an dieser Stelle eine Abwägung für ihr Projekt machen.
Zumindest bietet die App Engine unterschiedlichste Schnittstellen, die einen schnellen Entwicklungszyklus unterstützen.

Zu den gebräuchlichsten Schnittstellen gehören:

  • Speicherung von Objekten oder Blobs (Datenströhme)
  • Authentifikation (OAuth, OpenID)
  • Suchanfragen auf vorgegebene Datenstrukturen
  • XMPP Chat und E-Mail versant

Die ersten beiden Schnittstellen werden in den folgenden Abschnitten exemplarisch vorgestellt. Dabei wird Java als Programmiersprache verwendet. Dieser Javacode nutzt das App Engine SDK und läuft Serverseitig.

Schnittstelle: Persistierung

Allgemein kommen Webanwendungen nicht ohne eine Speicherlösung aus. Die App Engine bietet mehrere Möglichkeiten der Speicherung von Daten.

Derzeit existieren drei Varianten:

  • schemalose NoSQL App Engine Datastorage
  • relationale Google Cloud SQL Datenbank
  • Objekt und Datei Google Cloud Storage

Zur Veranschaulichung wird nun in zwei kurzen Programmcode Beispielen die Nutzung der ersten Variante gezeigt.

Um Daten in den Datastorage zu überführen, gibt es im Java SDK die Klasse DatastoreService der zum Speichern eine Entity entgegennimmt.

01 Entity dbEntity = new Entity("Log");
02 dbEntity.setProperty("date", date);
03 dbEntity.setProperty("input",` input);
04 DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
05 ds.put(dbEntity); 

Beim Erzeugen einer Entity Instanz in Zeile 01 wird dieser ein Namespace als Parameter übergeben vergleichbar mit dem Tabellennamen in relationalen Datenbanken. Durch das Anfügen von Properties in Zeile 02 und Zeile 03 lassen sich nun Daten an das Objekt anhängen, die dann in Zeile 05 durch das Speichern per DatastoreService persistiert werden.
Wird dieses Testprogramm nun auf einer App Engine Instanz ausgeführt, wird ein Eintrag in den Datastore im Namespace „Log“ erzeugt, dieser besteht aus einem ein Datum und ein Input Feld. Einträge lassen sich einfach über das Web Admin Interface im Bereich „Datastore Viewer“ einsehen:

App Engine Datastorage

Nun zum auslesen der eben gespeicherten Daten.

01 DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
02 Filter dateFilter = new Query.FilterPredicate("date", FilterOperator.EQUAL, queryDate);
03 Query query = new Query("Users").setFilter(dateFilter);
04 PreparedQuery preparedQuery = ds.prepare(query);
05 double anzahl = preparedQuery.countEntities();

Zum auslesen, von vorher gespeicherten Einträgen, bedient man sich der Klasse Query (Zeile 03), die als Parameter den Namespace auf den die Anfrage gestellt werden soll entgegennimmt. Optional kann der Query auch ein Filter angehängt werden, der hier in Zeile 02 erzeugt und in Zeile 03 bei der Erzeugung der Query gesetzt wird. Abschließend wird ein PreparedQuery Objekt erzeugt, dass einem die Ergebnismenge z.B. als Liste ausgeben kann. Im obigen Beispiel wurde in Zeile 5 nur nach der Anzahl der zurückgegebenen Ergebnisse gefragt.

Diese simplen Beispiele zeigen recht deutlich, wie einfach sich die Schnittstellen ansteuern lassen. Durch jeweils etwa fünf Programmcode Zeilen ließ sich das Speichern und das Auslesen aus einer Datenbank implementieren. Der Aufwand der Installation einer Datenbank inklusive ihrer Konfiguration entfiel. Auch das Einbinden von Treibern bzw. einzelner Bibliotheken war nicht nötig. Meist lässt sich das Einbinden des App Engine SDK’s direkt bei Projekterzeugung aktivieren und somit bedarf es eines geringeren Aufwands bei der Verwaltung von genutzten Bibliotheken und etwaigen Inkompatibilitäten.

Im nächsten Abschnitt wird kurz auf die Unterstützung der Zugangskontrolle (Authentifikation) seitens App Engine eingegangen.

Schnittstelle: Authentifikation

Der einfachste Weg mithilfe von App Engine ein Login System zu implementieren, ist die Nutzung von Google Accounts.

01 UserService userService = UserServiceFactory.getUserService();
02 if (userService.getCurrentUser() != null) {
03   result = "<p>Sie können sich hier <a href=\"" +
04	     userService.createLogoutURL("/") + "\">ausloggen</a>.</p>";
05 } else {
06   result = "<p>FEHLER: Bitte zuerst <a href=\"" +
07	      userService.createLoginURL("/") + "\">einloggen</a>.";
08 }

Hierfür steht die Klasse UserService (Zeile 03) zur Verfügung. An dieser kann abgefragt werden, ob der derzeitige Benutzer angemeldet ist (Zeile 02) und es können dann entsprechende Abmelde (Zeile 03) und Anmelde (Zeile 05) Links erzeugt werden.

Neben der Nutzung von Google Accounts lässt sich auch OpenID als Authentifikations Verfahren nutzen. Wie in der Abbildung zu sehen, lässt sich über das Web Admin Interface die gewünschte Variante auswählen, hier entsprechend ob sich alle Google Nutzer anmelden können, nur Nutzer einer definierten Google Apps Domain oder auch Nutzer von Diensten die OpenID unterstützen.

Authentifications Optionen

Mithilfe dieser Schnittstelle lässt sich sehr schnell eine Benutzersystem einbinden, was allerdings, im Fall der Nutzung von Google Accounts, eine starken Kopplung an die Google Infrastruktur zur Folge hat. Der nächste Abschnitt zeigt, welche Möglichkeiten die App Engine im Bereich der Skalierbarkeit zur Verfügung stellt.

Schnittstelle: Skalierung

Wie in der Einleitung schon erwähnt, ist ein weiterer Vorteil von PaaS, dass Anwendungen bei geringen Zugriffszahlen weniger Ressourcen verbrauchen und somit weniger Kosten im Betrieb nach sich ziehen. Um diesen Vorteil substanziell nutzen zu können, bedarf es Mechanismen, die eine automatische Skalierung erlauben.

Die App Engine bietet zwei Arten von Instanzen an:

  • Reservierte Instanzen, die immer laufen
  • Dynamische Instanzen, die bei Bedarf starten

Die reservierten Instanzen kosten mehr, haben jedoch den Vorteil, dass es keine initiale Verzögerung gibt. Diese entsteht, wenn dynamische Instanzen nach einem vorher definierten Zeitraum stoppen und erst durch eine weitere Anfrage wieder starten. Es ist gängige Praxis wenige reservierte Instanzen zu definieren, die entsprechend die Anfragen direkt beantworten und bei erhöhter Zugriffszahl weitere dynamische Instanzen zu starten.

Instanzenübersicht

Im Web Admin Interface lassen sich zusätzlich die akzeptierten Latenzzeiten einstellen. Braucht eine Instanz mehr Zeit für die Beantwortung einer Anfrage, werden weitere Instanzen hochgefahren. Bei einem simuliertem Ansturm auf eine Demoanwendung, wurde somit eine zweite Instanz automatisch hochgefahren.

Neben der automatischen Skalierung lassen sich Instanzen auch manuell oder per Konfigurationsdatei in der Anwendung hochfahren. Es ist auch möglich, dass die Anwendung selbst Instanzen hochfährt. Bei einem erkennbarem Muster im Userverhalten, kann dies nützlich sein. Ein Beispiel wäre erhöhte Zugriffszahlen auf ein Browserspiel, wenn viele Firmen Mittagspause haben. Für diesen Zeitraum kann die Anwendung weitere Instanzen hochfahren, um den Andrang zu bewältigen.

Integration in Entwicklungsprozess

Die Google App Engine bietet zwei Methoden um Anwendungscode auf ihren Instanzen laufen zu lassen. Einerseits mittels des SDK, das Kommandozeilen Programme mitbringt, mit denen kompilierte Anwendungen hochgeladen werden können und andererseits die Anbindung eines Git-Repository. Mittels Maven-Build Konfigurationen kann bei jedem Push in das Repository ein Build & Deploy ausgelöst werden.
Für die erste Variante, also das Hochladen von Anwendungen, gibt es z.B. in Eclipse Plugins, die diesen Prozess vereinfachen. Das Google Plugin für Eclipse bindet einen Button ein, mithilfe dessen - durch einen einfach Klick - ein Build und ein anschließender Deployvorgang ausgelöst wird. Dabei lassen sich auch Versionen definieren, womit es später möglich ist, mehrere Instanzen mit unterschiedlichen Versionen zu betreiben. Dies Verfahren ist auf jeden Fall für Testdeployments interessant.

Schlussworte

Abschließend lässt sich sagen, dass die Google App Engine den Entwicklungsprozess stark beschleunigen kann und sich besonders gut in agile Prozesse einbindet (Skalierbarkeit & wiederverwendung von Funktionskomponenten). Allerdings ist die Bindung an die jeweilige Plattform in die Abwägung einzubeziehen. Gerade für kleinere prototypische Anwendungen oder Anwendungen mit geringen oder sehr asymetrischen Zugriffsverhalten (Leerlaufzeiten) ist die App Engine sicherlich gut geeignet. Bei größeren und später auch kommerziellen Anwendungen, bleibt es eine Abwägung zwischen dem initialen Aufwand und der späteren Flexibilität.