Erstgespräch vereinbaren
Kommende Termine
4. Mai 2026
IT-Talk: Digitale Verantwortung
Details →
12. Juni 2026
Vernissage
28. September 2026
IT-Talk: Event-Driven Architecture

Reactive Application Toolkit: Vert.x - Erste Erfahrungen

Praxisbericht zu Vert.x: Event-Driven Architektur, Verticles, EventBus und Vergleich mit Akka für reaktive JVM-Anwendungen.

Netzwerk-Verbindungen

Was ist Vert.x?

Die Homepage beschreibt es als “tool-kit for building reactive applications on the JVM.” Vert.x referenziert das Reactive Manifesto und betont ereignisgesteuerte und nicht-blockierende Eigenschaften, die in seinem Kern verankert sind. Entwickler müssen Responsiveness, Resilience und Elasticity eigenständig sicherstellen.

Event-Driven Architektur

Traditionelle Application Server widmen einen Thread pro Request und verarbeiten synchron. Vert.x implementiert ein restriktiveres Modell: Event-Handler können nicht direkt auf externe Ressourcen zugreifen. Stattdessen bietet das Framework asynchrone APIs. Dieser Ansatz minimiert den Ressourcenverbrauch – Java-Threads werden auf OS-Threads abgebildet, und Kontextwechsel verursachen erhebliche CPU-Cache-Störungen.

Vert.x verwendet Event Loops (typischerweise eine pro CPU-Kern), wodurch Threads auf demselben Kern bleiben und Switching-Overhead eliminiert wird.

Toolkit vs. Framework

Vert.x positioniert sich als offenes Toolkit statt als geschlossenes Framework und setzt minimale Einschränkungen. Sein spezielles Threading-Modell unterscheidet sich jedoch grundlegend von konventionellen Java-Anwendungen, was die Integration mit externen Bibliotheken erschwert.

Polyglot-Unterstützung

APIs sind idiomatisch in Java, JavaScript, Groovy, Ruby und Ceylon verfügbar und unterstützen mehrere JVM-Sprachen.

General Purpose und Unopinionated

Am besten geeignet für Anwendungen, die zahlreiche parallele Netzwerkverbindungen verwalten. Komplexe Geschäftslogik mit umfangreichem Datenbankzugriff stellt eine Schwäche dar. Das unopinionierte Design bietet Flexibilität, schafft aber Herausforderungen beim Onboarding – Beispiele beschränken sich auf grundlegende Demonstrationen.

Mentales Modell

Verticles

Die zentrale Abstraktion umfasst ein zentrales Vertx-Objekt, das die Anwendungslogik durch Verticles koordiniert.

Drei Verticle-Typen:

  • Standard Verticles: Code wird innerhalb derselben Event Loop ausgeführt (single-threaded), blockierende Operationen sind verboten
  • Worker Verticles: Werden in dedizierten Thread-Pools ausgeführt und erlauben blockierende APIs
  • Multithreaded Worker Verticles: Fehlen Standardgarantien; erfordern manuelle Synchronisation

Beispiel für blockierende Ausführung:

vertx.executeBlocking(future -> {
  String result = someAPI.blockingMethod("hello");
  future.complete(result);
}, res -> {
  System.out.println("The result is: " + res.result());
});

EventBus

Das “Nervensystem”, das Verticle-Kommunikation ermöglicht via:

  • Unicast- oder Broadcast-Messaging
  • String-adressierte Kanäle
  • Keine Zustellungsgarantien
  • Begrenzte Datentyp-Unterstützung

Grundlegende Nutzung:

EventBus eb = vertx.eventBus();
eb.consumer("my.message.channel", message -> {
  System.out.println("I have received a message: " + message.body());
});

eb.publish("my.message.channel", "Sending some message");

Vert.x vs. Akka

Beide teilen identische Nebenläufigkeitsgarantien und API-Einschränkungen. Akka bietet tiefere Actor-Model-Unterstützung und überlegene Fehlerbehandlungsmechanismen. Vert.x bietet überlegene Web-Routing-Fähigkeiten und Polyglot-Sprachunterstützung. Akka glänzt bei der Domänenobjekt-Darstellung; Vert.x erfordert eigene Implementierungen.

Wichtige Eigenschaften

Datenbankzugriff

Vert.x bietet Clients für MongoDB, Redis und JDBC. Der JDBC-Wrapper negiert die reaktiven Vorteile – jede parallele Abfrage erfordert dedizierte Threads. Die asynchrone API wird unnötig komplex. Ein einfaches Transaktionsbeispiel umfasst 87 Zeilen Code. Echte asynchrone Clients existieren für MySQL/PostgreSQL, befinden sich aber in der technischen Vorschau.

Dokumentdatenbanken wie MongoDB stellen weniger Herausforderungen dar, da weniger Abfragen erforderlich sind.

Web-Unterstützung

Das Vert.x-Web-Modul bietet Routing, Pfadausdrücke, Content-Negotiation, Autorisierung und fünf Template-Engines. File-I/O-Einschränkungen in Event Loops begrenzen die Template-Engine-Funktionalität – Thymeleafs Internationalisierungs-Features werden unverfügbar.

Debugging-Herausforderungen

Call-Stacks werden unzuverlässig für die Identifizierung von Problemquellen. Breakpoints halten nur den unmittelbaren Thread an; Timeouts treten oft ohne synchrone Aufrufer zur Untersuchung auf. Traditionelle Debugging-Ansätze scheitern; Logging wird zum primären Diagnosetool.

Testing

Asynchrone Operationen erfordern Vert.x-spezifische Test-Infrastruktur. Standard-JUnit-Setups reichen nicht aus:

TestSuite suite = TestSuite.create("the_test_suite");
suite.test("async consumer received message", context -> {
  Async async = context.async();
  eventBus.consumer("the-address", msg -> {
    async.complete();
  });
  eventBus.publish("the-address", "some message");
});

Clustering

Eingebaute Clustering-Unterstützung ermöglicht automatisches Failover und bildet die Grundlage für horizontale Skalierbarkeit.

Bewertung

Die HTTP-Request-Verarbeitung operiert auf relativ niedrigen Abstraktionsebenen – flexibel, aber mit erheblichem manuellem Konfigurationsaufwand. Die Integration relationaler Datenbanken erweist sich als mühsam; traditionelle ORMs wie Hibernate werden ungeeignet. Die Optionen verengen sich auf einfachere Lösungen wie OrmLite, die mit Beziehungen Schwierigkeiten haben.

Der asynchrone JDBC-Ansatz erscheint kontraproduktiv: Datenbankaufrufe werden in Thread-Pool-Threads ausgeführt, die während der Operationen blockieren. Da der Datenbankzugriff typischerweise die Timing-Dominante in Geschäftsanwendungen ist, ergibt sich ein minimaler Gesamtvorteil, während sich die API-Komplexität vervielfacht.

Die Verwendung von RxJava Observables statt AsyncResults mildert die Callback-Verschachtelung durch Verkettung und zentralisiert die Fehlerbehandlung. Alternativ spiegelt das Bündeln von Anwendungslogik und Datenbankzugriff in Multithreaded Worker Verticles konventionelle Spring-Boot- oder Dropwizard-Ansätze wider, wodurch die Event-Loop-Leistungsgewinne entfallen.

Umfangreiche Callbacks erzeugen enge Vert.x-Kopplung; RxJava-Nutzung reduziert die Verflechtung und verbessert die Portabilität zu alternativen reaktiven Frameworks.

Zusammenfassung

Asynchrone reaktive Programmierung liefert sofortigen Mehrwert beim Parallelisieren unabhängiger Datenquellenabrufe (z.B. Begrüßungsseiten, die mehrere Microservices aggregieren). Anwendungen, die von seriellen Anfragen an synchrone Quellen (traditionelle Datenbanken) dominiert werden, erleiden Nachteile, die die Vorteile überwiegen. Gründliche Evaluierungsstudien sind vor einem Commitment unerlässlich.

Informationsquellen

  • Vert.x offizielle Dokumentation
  • “Vert.x - From zero to (micro)-hero” Tutorial
  • “Introduction to Vert.x” Blog-Serie
  • Online Shopping Microservices Blueprint
  • Hamcrest Matchers with Vert.x Unit
  • “Awesome Vert.x” Komponentenverzeichnis
  • “Reactive Development Using Vert.x” Artikel
  • Krzystof Urmans vierteilige Blog-Serie
  • Miel Donkers’ Real-World Use-Case Analyse
Zurück zum Blog