{"id":683,"date":"2026-06-09T00:35:16","date_gmt":"2026-06-08T23:35:16","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=683"},"modified":"2026-06-17T00:35:54","modified_gmt":"2026-06-16T23:35:54","slug":"eclipse-vert-x-reaktive-nicht-blockierende-anwendungen-in-java","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=683","title":{"rendered":"Eclipse Vert.x \u2014 Reaktive, nicht-blockierende Anwendungen in Java"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">W\u00e4hrend Frameworks wie Spring Boot auf einem Thread-pro-Request-Modell basieren \u2014 jeder HTTP-Request blockiert einen Thread \u2014 setzt&nbsp;<strong>Eclipse Vert.x<\/strong>&nbsp;von Grund auf auf asynchrone, nicht-blockierende Verarbeitung. Das Ergebnis: eine einzige JVM-Instanz kann zehntausende parallele Verbindungen handhaben, ohne dass der Thread-Pool kollabiert.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Das Event-Loop-Modell<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Vert.x basiert auf dem&nbsp;<strong>Reactor-Pattern<\/strong>: Ein oder mehrere Event-Loop-Threads verarbeiten eingehende Ereignisse (HTTP-Requests, Timer, Nachrichten) in einer Endlosschleife. Blockierende Operationen sind tabu \u2014 sie w\u00fcrden den gesamten Event-Loop lahmlegen.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Event Loop (Thread 1) --&gt; Handler 1 --&gt; Handler 2 --&gt; DB (non-blocking) --&gt; Resume\nEvent Loop (Thread 2) --&gt; Handler 3 --&gt; HTTP-Call (non-blocking) --&gt; Resume\nEvent Loop (Thread N) --&gt; Handler 4 --&gt; Handler 5 --&gt; Handler 6 --&gt; Done\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Grundbaustein: Das Verticle<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Die Grundeinheit in Vert.x ist das&nbsp;<strong>Verticle<\/strong>&nbsp;\u2014 eine leichtgewichtige Komponente, die vom Event-Loop ausgef\u00fchrt wird:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> io.vertx.core.VerticleBase;\n<span class=\"hljs-keyword\">import<\/span> io.vertx.core.Future;\n<span class=\"hljs-keyword\">import<\/span> io.vertx.ext.web.Router;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">HttpServerVerticle<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">VerticleBase<\/span> <\/span>{\n\n    @Override\n    public Future&lt;?&gt; start() {\n        Router router = Router.router(vertx);\n\n        router.get(<span class=\"hljs-string\">\"\/hello\"<\/span>).handler(ctx -&gt; {\n            ctx.response()\n                .putHeader(<span class=\"hljs-string\">\"content-type\"<\/span>, <span class=\"hljs-string\">\"text\/plain\"<\/span>)\n                .end(<span class=\"hljs-string\">\"Hallo von Vert.x 5!\"<\/span>);\n        });\n\n        <span class=\"hljs-keyword\">return<\/span> vertx.createHttpServer()\n            .requestHandler(router)\n            .listen(<span class=\"hljs-number\">8080<\/span>)\n            .onSuccess(server -&gt;\n                System.out.println(<span class=\"hljs-string\">\"Server l\u00e4uft auf Port \"<\/span> + server.actualPort())\n            );\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Alle Handler-Callbacks werden vom Event-Loop ausgef\u00fchrt \u2014 niemals blockieren!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Der Event Bus<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kommunikation zwischen Verticles erfolgt \u00fcber den&nbsp;<strong>Event Bus<\/strong>, eine verteilte, lose gekoppelte Nachrichten-Infrastruktur:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;em&gt;<span class=\"hljs-comment\">\/\/ Consumer-Verticle&lt;\/em&gt;<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OrderVerticle<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">VerticleBase<\/span> <\/span>{\n    @Override\n    <span class=\"hljs-keyword\">public<\/span> Future<span class=\"hljs-meta\">&lt;?<\/span>&gt; start() {\n        vertx.eventBus().consumer(<span class=\"hljs-string\">\"bestellung.neu\"<\/span>, message -&gt; {\n            String payload = (String) message.body();\n            System.out.println(<span class=\"hljs-string\">\"Neue Bestellung: \"<\/span> + payload);\n            message.reply(<span class=\"hljs-string\">\"Bestellung verarbeitet\"<\/span>);\n        });\n        <span class=\"hljs-keyword\">return<\/span> Future.succeededFuture();\n    }\n}\n\n&lt;em&gt;<span class=\"hljs-comment\">\/\/ Producer-Verticle&lt;\/em&gt;<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ProducerVerticle<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">VerticleBase<\/span> <\/span>{\n    @Override\n    <span class=\"hljs-keyword\">public<\/span> Future<span class=\"hljs-meta\">&lt;?<\/span>&gt; start() {\n        <span class=\"hljs-keyword\">return<\/span> vertx.eventBus().request(<span class=\"hljs-string\">\"bestellung.neu\"<\/span>, <span class=\"hljs-string\">\"B-1234\"<\/span>)\n            .onSuccess(reply -&gt; System.out.println(<span class=\"hljs-string\">\"Antwort: \"<\/span> + reply.body()))\n            .onFailure(err -&gt; System.err.println(<span class=\"hljs-string\">\"Fehler: \"<\/span> + err.getMessage()));\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Der Event Bus unterst\u00fctzt Publish\/Subscribe, Request\/Response und kann \u2014 mit Clustering \u2014 sogar JVM-\u00fcbergreifend kommunizieren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nicht-blockierender Datenbankzugriff<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Blockierende JDBC-Aufrufe sind im Event-Loop t\u00f6dlich. Vert.x bietet mit dem&nbsp;<strong>SQL Client<\/strong>&nbsp;eine vollst\u00e4ndig asynchrone Alternative:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> io.vertx.jdbcclient.JDBCPool;\n<span class=\"hljs-keyword\">import<\/span> io.vertx.jdbcclient.JDBCConnectOptions;\n<span class=\"hljs-keyword\">import<\/span> io.vertx.sqlclient.Pool;\n<span class=\"hljs-keyword\">import<\/span> io.vertx.sqlclient.PoolOptions;\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Pool anlegen<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\nJDBCConnectOptions connectOptions = <span class=\"hljs-keyword\">new<\/span> JDBCConnectOptions()\n    .setJdbcUrl(<span class=\"hljs-string\">\"jdbc:postgresql:\/\/localhost:5432\/shop\"<\/span>);\nPoolOptions poolOptions = <span class=\"hljs-keyword\">new<\/span> PoolOptions()\n    .setMaxSize(<span class=\"hljs-number\">16<\/span>);\nPool pool = JDBCPool.pool(vertx, connectOptions, poolOptions);\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Asynchrone Query<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\npool.query(<span class=\"hljs-string\">\"SELECT * FROM produkte WHERE preis &gt; 19.99\"<\/span>)\n    .execute()\n    .onSuccess(rows -&gt; {\n        <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">var<\/span> row : rows) {\n            System.out.println(row.getString(<span class=\"hljs-string\">\"name\"<\/span>));\n        }\n    })\n    .onFailure(err -&gt; {\n        System.err.println(<span class=\"hljs-string\">\"Fehler: \"<\/span> + err.getMessage());\n    });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr PostgreSQL steht zudem der&nbsp;<strong>PgClient<\/strong>&nbsp;bereit \u2014 ein nativer, reaktiver Client, der ohne JDBC-Layer direkt \u00fcber das PostgreSQL-Wire-Protokoll kommuniziert und seit Vert.x 5 \u00fcber den&nbsp;<code>PgBuilder<\/code>&nbsp;konfiguriert wird.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reaktive Alternativen: Mutiny und Virtual Threads<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Neben RxJava unterst\u00fctzt Vert.x 5 auch&nbsp;<strong>SmallRye Mutiny<\/strong>&nbsp;\u2014 eine eigenst\u00e4ndige reaktive Programmierbibliothek, die als moderne Alternative zu RxJava positioniert ist. Mutiny bietet zwei Programmiermodelle: eine ereignisgesteuerte API (<code>Multi<\/code>\/<code>Uni<\/code>) und eine imperative, Coroutine-\u00e4hnliche Variante.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr Entwickler, die blockierende APIs anbinden m\u00fcssen, bietet Vert.x seit dem&nbsp;<strong>Virtual-Threads-Incubator<\/strong>&nbsp;eine elegante L\u00f6sung: Blockierende Aufrufe k\u00f6nnen in virtuellen Threads ausgef\u00fchrt werden, ohne den Event-Loop zu blockieren. Seit Java 21 sind Virtual Threads fester Bestandteil der Plattform:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">vertx.executeBlocking(() -&gt; {\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ L\u00e4uft in einem virtuellen Thread \u2014 blockierende Aufrufe sind hier sicher<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span>\n    return legacyBlockingService.fetchData();\n}).onSuccess(result -&gt; {\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Zur\u00fcck im Event-Loop<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span>\n    System.out.println(\"Ergebnis: \" + result);\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Reaktive Streams mit RxJava<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Vert.x l\u00e4sst sich direkt mit&nbsp;<strong>RxJava<\/strong>&nbsp;kombinieren (Pull-Abh\u00e4ngigkeit&nbsp;<code>vertx-rx-java3<\/code>):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> io.vertx.rxjava3.core.AbstractVerticle;\n<span class=\"hljs-keyword\">import<\/span> io.vertx.rxjava3.ext.web.Router;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RxVerticle<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">AbstractVerticle<\/span> <\/span>{\n    @Override\n    public <span class=\"hljs-keyword\">void<\/span> start() {\n        Router router = Router.router(vertx);\n\n        router.get(<span class=\"hljs-string\">\"\/users\/:id\"<\/span>).handler(ctx -&gt; {\n            <span class=\"hljs-built_in\">String<\/span> id = ctx.pathParam(<span class=\"hljs-string\">\"id\"<\/span>);\n\n            dbClient.preparedQuery(<span class=\"hljs-string\">\"SELECT * FROM users WHERE id = $1\"<\/span>)\n                .rxExecute(Tuple.of(Integer.parseInt(id)))\n                .map(rows -&gt; rows.iterator().next())\n                .subscribe(\n                    row -&gt; ctx.response().end(row.toJson().encode()),\n                    err -&gt; ctx.fail(<span class=\"hljs-number\">500<\/span>, err)\n                );\n        });\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><code>.rxExecute()<\/code>&nbsp;wandelt das Future-basierte Vert.x-API in eine RxJava-Single um \u2014 f\u00fcr flie\u00dfende reaktive Pipelines.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wann Vert.x?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Vert.x ist besonders interessant f\u00fcr:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Hochskalierende Echtzeit-Anwendungen (Chat, Gaming, B\u00f6rsenticker)<\/li>\n\n\n\n<li>API-Gateways und Proxies mit minimalem Overhead<\/li>\n\n\n\n<li>Teams, die ein reaktives Modell mit leichtgewichtigem Toolkit einem Full-Stack-Framework vorziehen<\/li>\n\n\n\n<li>Polyglotte Projekte (Vert.x unterst\u00fctzt Java, Kotlin, Groovy und JavaScript)<\/li>\n\n\n\n<li>Microservices mit nativer Unterst\u00fctzung f\u00fcr OpenTelemetry, Health Checks und Circuit Breaker<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Vert.x ist kein Framework, sondern ein Toolkit: leichtgewichtig, unaufdringlich und extrem performant. Es zwingt Entwickler, in Ereignissen zu denken \u2014 blockierende Aufrufe sind strukturell unm\u00f6glich. Wer bereit ist, das Future-basierte Programmiermodell (oder RxJava) zu akzeptieren, wird mit einer Skalierbarkeit belohnt, die traditionelle Servlet-basierte Frameworks nicht erreichen. Mit der aktuellen Version 5.1.2 ist Vert.x erwachsen geworden \u2014 stabil, gut dokumentiert und produktionserprobt.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>W\u00e4hrend Frameworks wie Spring Boot auf einem Thread-pro-Request-Modell basieren \u2014 jeder HTTP-Request blockiert einen Thread \u2014 setzt&nbsp;Eclipse Vert.x&nbsp;von Grund auf auf asynchrone, nicht-blockierende Verarbeitung. Das Ergebnis: eine einzige JVM-Instanz kann zehntausende parallele Verbindungen handhaben, ohne dass der Thread-Pool kollabiert. Das Event-Loop-Modell Vert.x basiert auf dem&nbsp;Reactor-Pattern: Ein oder mehrere Event-Loop-Threads verarbeiten eingehende Ereignisse (HTTP-Requests, Timer, Nachrichten) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-683","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/683","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=683"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/683\/revisions"}],"predecessor-version":[{"id":684,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/683\/revisions\/684"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}