Kolumne: EnterpriseTales

Es tut sich was im Web: Servlet 4.0 mit HTTP/2

Lars Röwekamp, Arne Limburg

Mit jeder neuen Java-EE-Version gibt es auch eine neue Servlet-Version. Diese Regel gilt schon seit J2EE 1.2, und sie wird auch mit Java EE 8 Bestand haben. Der Plan lautet, dass mit Java EE 8 Servlet 4.0 ausgeliefert wird. Neu ist allerdings, dass die neue Servlet-Spezifikation auf einer neuen HTTP-Version basiert. Alle bisherigen Servlet-Versionen seit 2.3 basieren auf HTTP/1.1, das es seit 1999 gibt.

Die Servlet-Spezifikation gibt es seit 1997. Servlet 2.x hatte dabei eine Gültigkeit von über zehn Jahren, bis es dann 2009 von Servlet 3.0 ersetzt wurde. Servlet 3.0 brachte Dependency Injection und Asynchronität. Welchen Sinn ergibt es da, nun erneut ein Major-Release herauszubringen? Was ist von Servlet 4.0 zu erwarten? Die Antwort darauf wird diese Kolumne liefern.

Der Auslöser für das Starten eines neuen Major-Releases der Servlet Spec war das sich abzeichnende Release eines neuen HTTP-Standards. Im August 2014 wurde die Arbeit an HTTP/2 gestartet. Dies sahen die Macher der Servlet Spec als so bedeutend an, dass auf dieser Basis Servlet 4.0 begonnen wurde. Man ging mit Servlet 4.0 also gewissermaßen in Vorleistung, wobei ein gewisses Risiko bestand, dass HTTP/2 nicht rechtzeitig zum geplanten Erscheinungsdatum von Servlet 4.0 fertig werden würde. Mittlerweile hat sich dieses Risiko aber erledigt. Im Mai dieses Jahres wurde der RFC 7540 veröffentlicht, der HTTP/2 spezifiziert. Aber was ist HTTP/2 genau? Was bringt es für Neuerungen, dass es sich lohnt, eine eigene Servlet-Spezifikation darauf basieren zu lassen?

Schwächen von HTTP 1

Ladezeiten für Webseiten spielen trotz immer schneller werdender Internetverbindungen nach wie vor eine große Rolle bei der Webentwicklung. Und so verwundert es nicht, dass Neuentwicklungen des Kommunikationsprotokolls auch immer das Thema Performance im Auge haben.

Ein großer Teil der Ladezeit vergeht damit, dass Client-Server-Verbindungen auf- und wieder abgebaut werden. Daher ist es eine logische Folge, dass versucht wird, die Anzahl der auf- und abgebauten Verbindungen zu minimieren. Dies ist bereits in HTTP/1.1 mit dem Pipelining geschehen. Dabei wird eine Client-Server-(TCP-)Verbindung für mehrere HTTP-Requests wiederverwendet. Das funktioniert zwar zunächst gut, allerdings stößt man hier auf das Head-of-Line-Blocking-Problem. Dieses Problem tritt auf, weil der HTTP-Standard garantiert, dass HTTP-Requests der Reihe nach abgearbeitet werden. Geht z. B. der zweite von drei Requests verloren, kann auch der dritte nicht ausgeliefert werden, bis der zweite erneut angefragt ist. Auch alle weiteren Requests an denselben Server sind blockiert.

HTTP-Ergänzungen wie z. B. WebSockets sind weitere Versuche, dem Problem des Auf- und Abbaus von Verbindungen zu begegnen. Parallel dazu wurde von Google das Protokoll SPDY (sprich: speedy) entwickelt, das auch zum Ziel hatte, die beschriebenen Schwachstellen von HTTP 1 zu beheben. SPDY wurde seither von Chrome unterstützt, bevor Firefox und der Internet Explorer ab ihren Versionen 11 nachzogen.

The Rise of HTTP/2

Im August 2014 formierte sich die Working Group für die Spezifikation von HTTP/2, und am 16. Dezember wurde der Antrag eingereicht, HTTP/2 als Standard zu akzeptieren. Durch die Vorarbeit, die bei SPDY geleistet worden war, konnte die Spezifikation von HTTP/2 recht zügig erfolgen, sodass es bereits am 17. Februar 2015 als Standard bestätigt wurde. Veröffentlicht wurde HTTP/2 am 14. Mai 2015.

Ziele von HTTP/2 sind neben der deutlichen Verringerung der Latenz eine weitgehende Kompatibilität zu HTTP 1. So wurden die Methods (GET, POST, …), Statuscodes und URIs beibehalten, und es ist Client und Server möglich, auszuhandeln, ob sie HTTP 1.1, 2.0 oder sogar ganz andere Protokolle (wie z. B. SPDY) zur Kommunikation verwenden wollen. Google hat allerdings bereits angekündigt, den Chrome-Support für SPDY mit der Spezifikation von HTTP/2 einzustellen.

Die geringere Latenz erreicht HTTP/2 durch mehrere Faktoren. Einerseits wird das bereits erwähnte Head-of-Line-Problem gelöst, indem jeder Aktion eine Stream-ID zugewiesen wird. Durch diese können unterschiedliche Requests und Responses auf einem TCP-Kanal auseinandergehalten werden, was erlaubt, dass mehrere Responses auf einem Kanal parallel geladen werden können. Um aus diesem Feature den größtmöglichen Nutzen zu ziehen, gibt es zusätzlich die Möglichkeit, dass der Server URLs zum Client pusht; so könnte der Server beispielsweise alle URLs zu den benötigten CSS- und JS-Dateien zum Client pushen, wenn der Client eine HTML-Seite anfragt. Der Server weiß dann ja bereits, dass der Client (vermutlich) die verlinkten CSS- und JS-Dateien auch benötigen wird. Dank des Push-Mechanismus könnten dann alle Ressourcen parallel auf einem Stream geladen werden, wodurch eine erheblich geringere Latenz erreicht wird. Zusätzlich wird es eine Priorisierung von Streams geben und die Möglichkeit, den Request-Header zu komprimieren. So wird der Server die Headerdaten innerhalb eines TCP-Kanals aufheben, sodass nachfolgende Requests nur abweichende Headerfelder übertragen müssen.

Dass das Ziel der geringeren Latenz mit HTTP/2 tatsächlich erreicht wird, davon ist aufgrund der Erfahrung mit SPDY auszugehen.

Kritik an HTTP/2

Kritisch gesehen wird der kurze Zeitraum, in dem die Spezifikation auf den Weg gebracht wurde. Dadurch wurde SPDY als Grundlage durch Google geradezu aufgezwungen. Ein komplettes Neudenken war in diesem Zeitraum praktisch nicht möglich und alternative Ansätze wurden nicht in Erwägung gezogen. Zunächst wurde auch diskutiert, ob ein Zwang zur Verschlüsselung in das Protokoll aufgenommen werden sollte. Dieses Vorhaben wurde aber wieder verworfen. Auch opportunistische Verschlüsselung (Opportunistic Encryption) wurde nicht aufgenommen. Dabei handelt es sich um die Möglichkeit einer Seite, zunächst einen verschlüsselten Verbindungsaufbau zu versuchen und bei einem Fehlschlag (z. B. wenn die Gegenseite nicht in der Lage ist zu verschlüsseln) auf unverschlüsselte Verbindungen zurückzufallen.

Servlet 4.0

Alle hier genannten Neuerungen rechtfertigen natürlich eine neue Servlet-Spezifikation und sicherlich auch ein Major-Update. So ist es auch kein Wunder, dass alle hier genannten Punkte auf der Agenda der Servlet Spec auftauchen.

Letztendlich bleibt für das Servlet-Spec-Komitee nur die Aufgabe, alle Neuerungen von HTTP/2 in ein Java-API zu gießen und gleichzeitig eine Abwärtskompatibilität zu Servlet 3 und HTTP 1 zu gewährleisten. So wird es in den Klassen HttpServletRequest und HttpServletResponse sicherlich die zusätzliche Methode getStreamId() geben [4], die dann natürlich auch bei einem HTTP-1-Client einen sinnvollen Wert liefern muss. Zusätzlich wird es Methoden geben, um Streams zu priorisieren. Interessant werden sicherlich die Methoden für den Push-Support werden. Die Methode zum Pushen könnte z. B. im HttpServletRequest sitzen und dispatchPushRequest(…) heißen.

Viel wichtiger als das API für HTTP/2 wird es sein, dass die Java EE Specifications, die auf der Servlet Spec aufbauen, in ihren nächsten Versionen auch HTTP/2- (und damit z. B. Push-)Support bieten. So wäre es wichtig, dass Specs wie JSF und Web MVC mit ihren nächsten Versionen automatisch Resource-URLs pushen, sodass Entwickler sich darum nicht kümmern müssen und dennoch von den Geschwindigkeitsvorteilen profitieren.

Fazit

Auch wenn HTTP/2 einige Kritikpunkte aufweist, ist es ein großer Schritt in die richtige Richtung. Die Unterstützung von HTTP/2 in Servlet 4.0 ist daher folgerichtig. Wichtig ist, dass das Servlet-4.0-API möglichst früh in einem stabilen Zustand ist, damit darauf aufsetzende Spezifikationen wie JAX-RS, Web MVC und JSF die neuen Features bei sich nutzen können. Aber auch da ist Servlet 4.0 auf einem guten Weg.

Es lässt sich also sagen: Es tut sich was im Web. Wenn alle Specs die neuen Möglichkeiten optimal ausnutzen, ist in Java EE 8 mit einer signifikanten Performancesteigerung von Webanwendungen zu rechnen, ohne dass Anwendungsentwickler eine Zeile Code dafür schreiben müssen. In diesem Sinne: Stay tuned.

Geschrieben von
Lars Röwekamp
Lars Röwekamp
Lars Röwekamp ist Gründer des IT-Beratungs- und Entwicklungsunternehmens open knowledge GmbH, beschäftigt sich im Rahmen seiner Tätigkeit als „CIO New Technologies“ mit der eingehenden Analyse und Bewertung neuer Software- und Technologietrends. Ein besonderer Schwerpunkt seiner Arbeit liegt derzeit in den Bereichen Enterprise und Mobile Computing, wobei neben Design- und Architekturfragen insbesondere die Real-Life-Aspekte im Fokus seiner Betrachtung stehen. Lars Röwekamp, Autor mehrerer Fachartikel und -bücher, beschäftigt sich seit der Geburtsstunde von Java mit dieser Programmiersprache, wobei er einen Großteil seiner praktischen Erfahrungen im Rahmen großer internationaler Projekte sammeln konnte.
Arne Limburg
Arne Limburg
Arne Limburg ist Softwarearchitekt bei der open knowledge GmbH in Oldenburg. Er verfügt über langjährige Erfahrung als Entwickler, Architekt und Consultant im Java-Umfeld und ist auch seit der ersten Stunde im Android-Umfeld aktiv.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.