Software Engineering

Leichtgewichtige, skalierbare Webanwendungen mit Vert.x

Node.js ist mittlerweile ein weit verbreitetes Framework, das auf Basis von JavaScript leichtgewichtige Application-Server realisieren kann. Häufig sucht man aber nach einem ähnlichen Framework, das andere Programmiersprachen, wie zum Beispiel Java, unterstützt. Hier bietet sich Vert.x an. Vert.x ist in Java geschrieben. Es wurde von Node.js inspiriert, sollte aber nicht wie Node.js für Java verstanden werden. Was Vert.x genau ist und wie es funktioniert, wird im Folgenden erklärt.

Vert.x – was ist das?

Vert.x ist eine leichtgewichtige, polyglotte, eventgetriebene Lösung zum Erstellen eines Backends für Web-Applikationen sowie zum Erstellen von Application-Servern. Dabei ist Vert.x sehr effizient, wie hier gezeigt wird.

Wie ist Vert.x aufgebaut?

Die Vert.x Architektur in Java

Ein Host kann im allgemeinen mehrere JVMs bereitstellen. Jede Vert.x Instanz arbeitet dabei auf einer eigenen JVM Instanz. Jede Vert.x Instanz besitzt eigene Verticles. Die Kommunikation findet in aller Regel über den in Vert.x beinhalteten verteilten Eventbus statt.

Was ist ein Verticle?

Ein Verticle ist ein Bereitstellungselement, welches von Vert.x ausgeführt wird. Man kann sich ein Verticle wie eine Ausführungseinheit für den Code vorstellen. Verticle verarbeiten Events und können wieder weitere Events emittieren. Dabei spielt es keine Rolle, an welchem Knoten im Netzwerk das Verticle sitzt. Es kann über den Eventbus mit den anderen Verticles kommunizieren. Das Schöne daran: Durch die Mehrsprachigkeit von Vert.x spielt es keine Rolle in welcher der von Vert.x unterstützten Programmiersprachen einzelne Verticles geschrieben sind. Darüber hinaus wird der Code eines Verticles nie gleichzeitig ablaufend in verschiedenen Threads ausgeführt. Ein Programmierer muss sich deshalb nicht mit komplexen Fragestellungen zur Thread-safty auseinandersetzen.

Wie funktioniert die Kommunikation?

Über den Eventbus. Der Eventbus ist die Schnittstelle zwischen dem Vert.x Server-Verticle, den anderen Vert.x Verticles sowie der Clientseite. Für die Kommunikation zwischen verschiedenen Verticles in einer Vert.x Instanz stehen außerdem noch SharedMaps und SharedSets zur Verfügung. Bei diesen handelt sich um Datenobjekte, welche über den Speicher für die einzelnen Verticles der Instanz erreichbar sind.

Für die Kommunikation über den Eventbus bietet Vert.x verschiedene Möglichkeiten. Es wird sowohl die typische Publisher/Subscriber Architektur als auch das Point-to-Point Mapping unterstützt. In der Regel findet die Kommunikation asynchron statt. Genau so einfach sind aber auch synchrone Nachrichtenverläufe mit Antworten auf gesendete Nachrichten möglich. Dadurch kann auch eine komplexere Kommunikation auf Grundlage einer Nachrichtenkette zwischen zwei Teilnehmern realisiert werden.

Über den Eventbus und die Shared-Datenstrukturen können nur Primitive sowie Strings versendet, beziehungsweise gespeichert werden. Wie kann ich dann aber komplexe Datenobjekte versenden? Die Antwort ist einfach: Mittels Java Script Object Notation kurz JSON. JSON ist mittlerweile als kompaktes, gut lesbares Datenformat zum Nachrichtenaustausch akzeptiert. Es gibt so gut wie in jeder verbreiteten Programmiersprache entsprechende Parser. Dadurch bietet es sich an, bei der Kommunikation auf JSON zurückzugreifen. Dadurch dass der Eventbus mit entsprechenden Javascript-Bibliotheken bis auf den Client hin ausgeweitet werden kann, wird diese Art der Kommunikation in Kombination mit der Verwendung von beispielsweise AngularJS auf der Clientseite zu einem Kinderspiel.

Wie skaliert Vert.x?

Die Vert.x Instanzen werden in einem sogenannten Event-Loop ausgeführt. Dabei warten gerade nicht benötigte Verticles und sind sofort einsatzbereit wenn Arbeit anfällt. Die Rechenzeit wird dabei zwischen den Verticles aufgeteilt.

Benötigt man mehr Verticle-Instanzen um beispielsweise eine hohe Anfragelast zu bewältigen, so kann man zur Laufzeit neue Verticles erzeugen. Diese können dann im Event-Loop eingereiht werden. Um einen etwaigen Overhead durch das Erstellen von Instanzen zu vermeiden, kann auch bereits zum Programmstart festgelegt werden, wie viele Instanzen eines bestimmten Verticles zu erstellen sind.

Durch den Event-Loop Mechanismus skaliert Vert.x außerordentlich gut, jedoch gilt es eine Regel zu beachten: „Führe niemals blockierenden Code oder langläufige Berechnungen im Event-Loop aus“. Wie kann ich in diesem Fall komplexe Anfragen realisieren? Reguläre JDBC-Datenbanktreiber arbeiten mit einer synchronen blockierenden Logik. Möchte man nun also Datenbankanfragen oder komplexere Berechnungen durchführen, bietet Vert.x neben den „normalen“ Verticles noch sogenannte „Worker-Verticles“ an. Diese erlauben die Ausführungen von blockierendem Legacy-Code. Wodurch dem prinzipiellen Einsatz von Vert.x keine Grenzen mehr gesetzt sind.

Vert.x ist leichtgewichtig!

Man benötigt nur wenige Zeilen um einen kompletten Webserver einzurichten. Dabei benötigt man weder einen Servlet-Container noch einen Application-Server. Es wird einfach eine Java Klasse erstellt, die das von Vert.x gelieferte Verticle Interface implementiert. Die Logik kann nun in Verticles gekapselt werden und Verticles können über den Eventbus miteinander kommunizieren.

Durch diese lose Kopplung ist es insbesondere möglich, jedes Verticle einzeln zu deployen. Eine engere Verknüpfung der Verticles ist hier nicht nötig. Auch ein dynamisches Deployment zur Laufzeit ist somit realisierbar.

Wie könnte also so ein Application-Server mit Vert.x realisiert werden?

Man könnte folgendermaßen vorgehen, dabei wird auf der Clientseite AngularJS verwendet.

Zunächst implementiert man einen leichtgewichtigen HTTP-Server. Dieser bekommt einen HTTPRequestHandler zugesichert. Der wiederum dafür sorgt, dass die von Angular angefragten Ressourcen geladen werden und dem Client zugänglich sind. Es wäre auch denkbar, das Routing durch Vert.x zu realisieren.

Um die Kommunikation zwischen der JavaScript-Applikation unter AngularJS und dem HTTP-Server zu ermöglichen, erstellt man aus Vert.x heraus zudem noch einen SockJSServer. Auf diesen Server lässt sich nun der Eventbus registrieren und die Kommunikation zwischen Client und Server ist gewährleistet.

Zuletzt wird dem Server noch ein Port übergeben, auf welchen er hören soll.

Alles in Allem

Vert.x ist ein Framework das dem Trend der Microservice-Architekturen folgt und vielseitige Einsatzgebiete besitzt.
Die gute Skalierbarkeit, die unabhängigen, verteilten Verticles sowie die effektive Ressourcennutzung machen Vert.x zu einer spannenden Alternative zu herkömmlichen Application-Servern. Dabei ist insbesondere die Kombination mit AngularJS und damit auch der Weg zu mobilen Webanwendungen hervorzuheben.

Related Posts

> Mobilität der Zukunft und wie sie für jeden erreichbar wird
> Mobile cross-platform Anwendungen mit AngularJS und Apache Cordova