Mit App Engine können Sie Webanwendungen erstellen, die die skalierbare Infrastruktur und Dienste von Google nutzen. App Engine führt Ihre Webanwendung mit einer Java 8-JVM aus. Zur Bearbeitung von Anfragen und zur Vorbereitung von Antworten in dieser Umgebung ruft App Engine die Servlet-Klassen Ihrer Anwendungen auf.
Die App Engine-Plattform bietet viele integrierte API-Dienste, die Ihr Code aufrufen kann. Außerdem kann Ihre Anwendung geplante Aufgaben konfigurieren, die in bestimmten Intervallen ausgeführt werden.
Java 8-Laufzeit für die Anwendung angeben
Damit Ihre Anwendung die Java
8-Laufzeit verwendet, fügen Sie der Datei appengine-web.xml
die folgende Zeile hinzu:
<runtime>java8</runtime>
Die in der Google Cloud-Befehlszeile unter platform/google_appengine/google/appengine/tools/java/lib/impl/appengine-api.jar
enthaltene Datei appengine-api.jar
stellt die App Engine API für Java dar. Sie können auf diese Datei auch über das Maven-Repository zugreifen, in dem alle Versionen aufgelistet sind.
Sie wählen die von Ihrer Anwendung verwendete Version der API aus, wenn Sie diese JAR-Datei in das Verzeichnis WEB-INF/lib/
der Anwendung aufnehmen oder Maven zur Verwaltung der Abhängigkeiten verwenden. Wenn eine neue Version der Java-Laufzeitumgebung mit Änderungen veröffentlicht wird, die mit vorhandenen Anwendungen nicht kompatibel sind, trägt diese Umgebung eine neue Hauptversionsnummer.
Abhängigkeiten mit Maven verwalten
Sie können Maven verwenden, um alle Abhängigkeiten zu verwalten. Dieserpom.xml
-Eintrag enthält beispielsweise die neueste App Engine API (Rappengine-api-1.0-sdk
), die von Maven Central verfügbar ist:
<dependency> <groupId>com.google.appengine</groupId> <artifactId>appengine-api-1.0-sdk</artifactId> <version></version> </dependency>
Sandbox
Die App Engine-Java-Laufzeit verteilt Anfragen für Anwendungen auf mehrere Webserver und verhindert somit, dass eine Anwendung eine andere beeinträchtigt. Eine App Engine-Anwendung darf nicht langsam reagieren. Eine an eine Anwendung gerichtete Webanfrage muss innerhalb des Zeitlimits der Anfrage verarbeitet werden. Prozesse, die dieses Antwortlimit überschreiten, werden beendet, um den Webserver nicht zu überlasten.Das einzige Verzeichnis, in das Nutzer Dateien schreiben können, ist /tmp
.
Dateien in /tmp
verbrauchen Arbeitsspeicher, der Ihrer Instanz zugeordnet ist. Die an diesem Ort gespeicherten Dateien sind nur für diese Instanz und nur für die Lebensdauer genau dieser Instanz verfügbar.
Die übliche Methode für Ihre Anwendung, Ressourcendateien abzurufen, besteht darin, die Dateien, auf die Sie angewiesen sind, unter WEB-INF
zu verpacken und dann mit Class.getResource()
, ServletContext.getResource()
oder ähnlichen Methoden aus Ihrer Anwendung zu laden.
Standardmäßig sind alle Dateien in der WAR "Ressourcendateien". Sie können Dateien aus diesem Satz mithilfe der Datei appengine-web.xml
ausschließen.
Reihenfolge der JARs zum Laden der Klassen
Manchmal muss die Reihenfolge, in der JAR-Dateien nach Klassen gescannt werden, neu definiert werden, um Konflikte zwischen Klassennamen zu lösen. In diesen Fällen können Sie für bestimmte JAR-Dateien eine Ladepriorität festlegen, indem Sie ein Element <class-loader-config>
mit Elementen von <priority-specifier>
zur Datei appengine-web.xml
hinzufügen. Beispiel:
<class-loader-config>
<priority-specifier filename="mailapi.jar"/>
</class-loader-config>
Hiermit wird die JAR-Datei "mailapi.jar
" als Erstes nach Klassen durchsucht und die Dateien im Verzeichnis war/WEB-INF/classes/
werden zurückgestellt.
Wenn Sie mehrere JAR-Dateien priorisieren, wird deren ursprüngliche Ladereihenfolge (in Bezug zueinander) verwendet. Die Reihenfolge der <priority-specifier>
-Elemente selbst spielt also keine Rolle.
Threads
Mit der Java 8-Laufzeit können Sie Threads über die ThreadManager API von App Engine und die in Java integrierten APIs wie new Thread()
erstellen.
Wenn Sie App Engine APIs (com.google.appengine.api.*
) aufrufen möchten, müssen Sie dies derzeit über einen Anfragethread oder einen Thread tun, der mit der ThreadManager API erstellt wurde.
Eine Anwendung kann
java.lang.Runnable
implementieren.- eine Thread-Factory durch Aufrufen von
com.google.appengine.api.ThreadManager.currentRequestThreadFactory()
erstellen. - die
newRequestThread
-Methode der Factory aufrufen und inRunnable
,newRequestThread(runnable)
übergeben oder das voncom.google.appengine.api.ThreadManager.currentRequestThreadFactory()
zurückgegebene Factory-Objekt mit einemExecutorService
verwenden (z. B.Executors.newCachedThreadPool(factory)
aufrufen).
Wenn Sie einen ThreadPoolExecutor
mit currentRequestThreadFactory()
erstellen, muss shutdown()
explizit aufgerufen werden, bevor die Servlet-Anfrage abgeschlossen ist. Andernfalls wird die Anfrage nicht abgeschlossen und der Anwendungsserver schließlich ausfallen.
Beachten Sie, dass einige Bibliotheken ThreadPoolExecutors für Sie erstellen.
Eine Anwendung kann Operationen gegen den aktuellen Thread machen, z. B. thread.interrupt()
.
Jede Anfrage ist auf 50 gleichzeitige App Engine API-Anfragethreads beschränkt.
Wenn Sie mit Threads arbeiten, sollten Sie Objekte mit hoher Gleichzeitigkeit wie Executor
und Runnable
verwenden. Diese kümmern sich um viele der subtilen, aber wichtigen Details der Gleichzeitigkeit wie Interrupts sowie Planung und Verwaltung.
Tools
Unterstützte IDEs
Mit Cloud Tools for IntelliJ können Sie App Engine-Anwendungen in IntelliJ IDEA ausführen und dort debuggen. Außerdem haben Sie die Möglichkeit, Ihre App Engine-Projekte in der Produktionsumgebung zu erstellen, ohne die IDE zu verlassen.
Unterstützte Buildtools
Mit den App Engine-Plug-ins für Apache Maven oder Gradle können Sie den Entwicklungsprozess beschleunigen:
Lokaler Entwicklungsserver
Während der Entwicklungs- und Testphase führt der Entwicklungsserver die Anwendung auf dem lokalen Computer aus. Der Server simuliert dabei die Datastore-Dienste. Der Entwicklungsserver erstellt auch die Konfiguration für Datenspeicherindizes anhand der Abfragen, die von der Anwendung während der Testphase durchgeführt werden.
Gleichzeitigkeit und Latenz
Die Latenz Ihrer Anwendung hat den größten Einfluss auf die Anzahl der Instanzen, die für die Verarbeitung Ihres Traffics erforderlich ist. Wenn Sie Anfragen schnell verarbeiten, kann eine einzelne Instanz viele Anfragen bewältigen.
Einzelthread-Instanzen können jeweils eine gleichzeitige Anfrage verarbeiten. Daher besteht ein direkter Zusammenhang zwischen der Latenz und der Anzahl der Anfragen, die pro Sekunde auf der Instanz verarbeitet werden können. Zum Beispiel entspricht eine Latenz von 10 ms 100 Anfragen pro Sekunde und pro Instanz.Multithread-Instanzen können viele gleichzeitige Anfragen verarbeiten. Daher besteht ein direkter Zusammenhang zwischen der beanspruchten CPU und der Anzahl der Anfragen pro Sekunde.
Java-Anwendungen unterstützen gleichzeitige Anfragen, sodass eine einzelne Instanz neue Anfragen verarbeiten kann, während sie auf den Abschluss anderer Anfragen wartet. Durch die Gleichzeitigkeit wird die Anzahl der Instanzen, die Ihre Anwendung benötigt, erheblich reduziert. Allerdings müssen Sie Multithreading beim Entwurf Ihrer Anwendung integrieren.
Wenn beispielsweise eine B4-Instanz (ca. 2,4 GHz) 10 Mega-Prozessorzyklen pro Anfrage beansprucht, können Sie 240 Anfragen pro Sekunde und pro Instanz verarbeiten. Bei 100 Mega-Prozessorzyklen pro Anfrage werden 24 Anfragen pro Sekunde und pro Instanz erreicht. Diese Zahlen sind der Idealfall, aber in Bezug auf den erreichbaren Durchsatz auf einer Instanz recht realistisch.
App Engine-Java-Releases
Alle freigegebenen Artefakte, die mit Version 2.x.x
beginnen, verwenden den Releasemechanismus Open Source. Freigegebene Artefakte, die mit Version 1.9.9xx
oder früher beginnen, verwenden das interne Build-System. Weitere Informationen finden Sie im GitHub-Repository.
Umgebungsvariablen
Folgende Umgebungsvariablen werden durch die Laufzeit festgelegt:
Umgebungsvariable | Beschreibung |
---|---|
GAE_APPLICATION
|
ID der App Engine-Anwendung. Diese ID hat das Präfix „region code~”, z. B. „e~” für Anwendungen, die in Europa bereitgestellt werden. |
GAE_DEPLOYMENT_ID |
ID der aktuellen Bereitstellung. |
GAE_ENV |
App Engine-Umgebung. Legen Sie standard fest. |
GAE_INSTANCE |
ID der Instanz, auf der Ihr Dienst gerade ausgeführt wird. |
GAE_RUNTIME |
Laufzeit, die in der Datei app.yaml angegeben ist. |
GAE_SERVICE |
Dienstname, der in der Datei app.yaml angegeben ist. Wenn kein Dienstname angegeben ist, wird als Wert default festgelegt. |
GAE_VERSION |
Aktuelle Versionsbezeichnung Ihres Dienstes. |
GOOGLE_CLOUD_PROJECT |
Google Cloud-Projekt-ID, die der Anwendung zugeordnet ist. |
PORT |
Port, der HTTP-Anfragen empfängt. |
Sie können zusätzliche Umgebungsvariablen in Ihrer app.yaml
-Datei definieren. Die oben genannten Werte können jedoch nicht überschrieben werden.