Diese leichtgewichtigen Java-Frameworks kombinieren Cloud-native Flexibilität mit der bewährten Architektur von Java, sodass Sie schnellen Code schreiben können, der sich überall leicht bereitstellen lässt. [...]
Die Java-Programmiersprache geht nun in ihr drittes Jahrzehnt, und die Sprache und ihr Bytecode haben in allen Bereichen, von eingebetteten Chips bis hin zu riesigen Serverfarmen, ein Zuhause gefunden. Javas Kombination aus einer grundsoliden virtuellen Maschine und einer großen Sammlung von Bibliotheken bildet ein fruchtbares Ökosystem zum Schreiben von Code, der überall läuft.
Ein Bereich, in dem sich Java jedoch schwer getan hat, ist die Welt der Server, die oft mit Verbindungen von Tausenden oder sogar Millionen von Benutzern jonglieren müssen. Zu Beginn gehörten die Java-Tools zu den besten für die Erstellung serverseitiger Anwendungen, die die Geschäftslogik für alle Benutzer umsetzten. Java-Frameworks wie J2EE, Hibernate, Spring und das grundlegende Java-Servlet-Modell machten es relativ einfach, leistungsfähige Webanwendungen zu erstellen.
Die Technologie florierte, bis JavaScript und Node.js aufkamen. Node.js erregte viel Aufmerksamkeit, und die Entwickler begannen, auf die JavaScript-Laufzeitumgebung umzusteigen. Dafür gab es im Allgemeinen zwei Gründe: Erstens begrüßten die Entwickler die Möglichkeit, denselben Code auf dem Server und einem Browser-Client auszuführen. Zweitens lieferten Node.js-Server dank ihres reaktiven Modells oft einen erheblich schnelleren Durchsatz.
Das Java Ökosystem
Das Java-Ökosystem passte sich dem Wettbewerb an. Zunächst übernahmen einige Entwickler Tools wie das Google Web Toolkit, das Java in JavaScript umwandelt. Als nächstes arbeiteten sie daran, Java auf dem Server zu beschleunigen.
Frühe Java-Frameworks für Server hatten eine Einschränkung: Für jede eingehende Anfrage wurde ein eigener Thread eingerichtet. Dies war zwar eine saubere Art, ein- und ausgehende Daten zu organisieren, aber auch sehr anstrengend. Die Erstellung eines Threads erfordert Tausende von Bytes an Overhead, wodurch die Anzahl der Benutzer, die ein Server bewältigen kann, begrenzt wurde. Node.js verwendete ein anderes Modell, das es ermöglichte, viel mehr Benutzer zu verwalten, ohne diesen Overhead zu verursachen.
In jüngerer Zeit haben Java-Entwickler Innovationen aus Node.js in den Java-Stack übernommen, insbesondere Cloud-native Java-Frameworks. Diese Frameworks imitieren den Ansatz von Node.js und unterstützen leichtgewichtige Funktionen, die auf Cloud-Maschinen laufen und schnell gestartet und beendet werden können.
Sie kommen ohne zusätzliche Bibliotheken aus, um eine schnelle Bereitstellung auf den kleinsten verfügbaren Serverinstanzen zu unterstützen. Cloud-native Java-Frameworks sind darauf ausgelegt, Konstellationen von Microservices zu unterstützen, die unabhängig voneinander installiert und neu gestartet werden können.
Sie werden in der Regel in Containern wie Docker oder Podman bereitgestellt, um schnellstmögliche Builds und Installationen zu ermöglichen.
Moderne Java-Entwickler, die eine Cloud-native Lösung suchen, haben eine Reihe von Optionen. Ein ideales Cloud-natives Java-Framework nutzt die umfassende Erfahrung, die in die Java-Plattform und ihre Bibliotheken von Drittanbietern investiert wurde, und passt sie so an, dass sie in der Cloud schneller und leichter ausgeführt werden können. Hier sind acht Java-Frameworks, die von Grund auf für die Cloud-native Entwicklung und Bereitstellung entwickelt wurden.
Micronaut
Die Entwickler von Micronaut wollten die besten Eigenschaften klassischer Java-Frameworks wie Spring und Grails – wie flexible Konfiguration und Dependency Injection – übernehmen, aber den großen Speicherbedarf und die langsamen Startvorgänge entfernen, die sie für die Entwicklung von Microservices weniger wünschenswert machten.
Sie haben sorgfältig Annotationen entwickelt, die genügend Informationen für Dependency Injections liefern, ohne die speicherfressende Reflexion, die in älteren Frameworks verwendet wird. Da ein Großteil der Micronaut-Konfiguration bereits bei der Kompilierung erledigt wird, läuft der Code schneller und leichter.
Das Framework wurde entwickelt, um eine Vielzahl von JVM-basierten Sprachen (derzeit Java, Kotlin und Groovy) zu unterstützen und sie in verschiedenen Clouds auszuführen. Vordefinierte Konfigurationsdateien vereinfachen die Bereitstellung des Servers oder der serverlosen Funktionen auf allen wichtigen Clouds, und es gibt gut geschriebene Dokumentationsseiten für alle wichtigen Datenbankverbindungen.
Die Entwickler von Micronaut wollen mit dem Framework auch gute Teamarbeit bei der Entwicklung unterstützen. Eine HttpClient-Implementierung wird mit dem Projekt gebündelt, um das Schreiben von Unit-Tests zu vereinfachen, ohne Micronaut zu verlassen oder mehr Arbeit hinzuzufügen. Diese Tests sind oft einfacher und umfassender als die für dynamische Frameworks erforderlichen Tests.
Micronaut ist nicht nur für die Entwicklung von Anwendungen mit Cloud-Funktionen geeignet. Das Framework ist allgemein genug, um traditionelle Funktionen und einige Desktop-Anwendungen zu unterstützen. Seine enge Integration mit GraalVM ermöglicht es, Micronaut für die Erstellung nativer Anwendungen zu verwenden.
Quarkus
Entwickler, die eine gut verständliche Mischung aus imperativem und reaktivem Code verwenden möchten, können sich an Quarkus wenden. Das Quarkus-Team begann damit, die häufigsten Anwendungsfälle für Cloud-native Entwicklung zu antizipieren, und erstellte dann das Framework mit Beispielen, die diese Anwendungsfälle mit so gut wie keiner Konfiguration unterstützen. Das Ergebnis kann einfach in einen Container gerollt und in einem Kubernetes-Cluster bereitgestellt werden.
Das Entwicklungsteam hat besonders darauf geachtet, dass die Startzeiten kurz sind, damit Kubernetes-Cluster schnell skaliert werden können. Dies ist ein ideales Merkmal für Funktionen, die sporadisch ausgeführt werden, da sie bis zu ihrem Aufruf in Bereitschaft bleiben können.
Eines der Ziele des Projekts besteht darin, viele bestehende Standards und Bibliotheken, die in der Java-Community verbreitet sind, zu übernehmen und zu erweitern. Zum Beispiel definieren JAX-RS-Annotationen die REST-Endpunkte. Die Konfiguration beginnt mit dem Eclipse MicroProfile. Das Entwicklungsteam von Quarkus hat außerdem mehr als 50 Standardbibliotheken integriert, so dass die Wahrscheinlichkeit groß ist, dass Sie bestimmte Design Patterns wiedererkennen werden.
Sie können das grundlegende Quarkus-Framework für eine Vielzahl von Diensten nutzen. Ab Quarkus 2.8 fördern die Quarkus-Entwickler behutsam das RESTeasy Reactive-Modell. Es ist die Standardoption, wenn Sie ein neues Projekt beginnen, aber Sie müssen es nicht verwenden. RESTeasy Reactive bietet eine einfachere, non-blocking Struktur und Muster. Anstatt jeder Anfrage einen Thread zuzuweisen, übernimmt eine Reihe von non-blocking Threads die gesamte E/A und ruft Ihren Code bei Bedarf auf.
Quarkus umfasst auch eine breite Palette von Einsatzmöglichkeiten. Auch wenn es heißt, dass es zuerst in Containern läuft, kann es auch auf Bare Metal laufen. Es gibt auch eine integrierte Konfigurationsoption namens Funqy, die das Erstellen von Funktionen vereinfacht, die von AWS Lambda, Azure Functions, Knative und einigen anderen Optionen akzeptiert werden.
Spring Cloud Functions
Java-Entwickler sind mit dem Spring-Framework gut vertraut, da es seit rund zwei Jahrzehnten die Grundlage für viele Projekte bildet. Die Spring-Entwickler haben sich entschlossen, eine neue Version zu entwickeln, die sich besser für den Einsatz in der Cloud und für verschiedene andere Aufgaben eignet. Die Funktionen in Spring Cloud Functions sind so konzipiert, dass sie leicht für eine Vielzahl von Aufgaben wie Webdienste, Stream-Verarbeitung oder Hintergrundarbeit eingesetzt werden können.
Das Spring Cloud Functions-Framework setzt viele der philosophischen Traditionen fort, die von Spring eingeführt wurden. Die Cloud-Funktionen in diesem Framework unterstützen einen reaktiven oder imperativen Stil sowie eine hybride Mischung aus beidem.
Die Unterstützung einer Vielzahl von Optionen ist ein großes Ziel des Projekts. Es gibt Adapter, die die Funktionen in AWS Lambda, Microsoft Azure, Apache OpenWhisk, Google Cloud Platform und einige andere gängige Cloud-Funktionsumgebungen einbinden. Es gibt auch Adapter für wichtige Streaming-Frameworks wie Apache Kafka, Solace und RabbitMQ sowie die eigenständige Option Spring Cloud Stream. Die Paketierung und Bereitstellung ist weitgehend automatisiert, sodass Sie sich auf die Entwicklung der Funktionen selbst konzentrieren können.
Das Spring Cloud Functions-Entwicklungsteam hat auch hart daran gearbeitet, viele der üblichen Fallstricke und Herausforderungen der Cloud-Bereitstellung zu bewältigen. Spring Cloud Skipper kann verwendet werden, um Deployments über mehrere Clouds hinweg zu jonglieren. Spring Cloud Sleuth hilft bei der Fehlersuche, indem es Datenflüsse nachverfolgt. Spring Cloud Security verwaltet viele der Aufgaben zur Absicherung einer Anwendung, damit nur die richtigen Personen die Funktionen ausführen können.
Das Projekt ist eine sehr gute Grundlage für die Verteilung von Geschäftsanwendungen über eine Vielzahl von Plattformen. Sobald Ihre Anwendungslogik in einem Cloud Function POJO gekapselt ist, kann sie in Dutzenden von verschiedenen Bereichen eingesetzt werden.
Vert.x
Die Schöpfer von Vert.x wollten ein besonders schnelles Framework schaffen, indem sie die Ereignisschleife vereinfachten und die Verbindung mit der Datenbank optimierten. Vert.x hat eine einzelne Ereignisschleife wie Node.js, die es ermöglicht, mehrere Verbindungen zu jonglieren, wenn die Ereignisse eintreffen. Außerdem nutzt es das Threading-Modell von Java, um Ereignisse mit mehreren Threads in einem Pool zu verarbeiten, die auf mehreren Kernen laufen können, wenn diese verfügbar sind.
Die Struktur soll auch die Erstellung der Pipeline zur Verarbeitung eines Ereignisstroms vereinfachen. Sie leiht sich Konstrukte wie Promises und Futures, um unübersichtlichen Code mit mehrschichtigen Callbacks zu vermeiden. Die asynchronen Optionen tragen dazu bei, sauberen, lesbaren Code zu erzeugen, der mit einfachen Ketten von Methodenaufrufen gefüllt ist, während sich die Ereignisse durch den Ereignisbus bewegen.
Das Vert.x-Entwicklungsteam ist nicht dogmatisch, was seine Vision angeht. Sie sagen oft, dass Vert.x ein Toolkit und kein Framework ist. Der Code ist modular aufgebaut, so dass Sie selbst entscheiden können, welche Funktionen Sie verwenden möchten, und eine Architektur zusammenstellen können, die zu Ihrer Anwendung passt. Programmierer, die eher eine imperative als eine reaktive Struktur wünschen, finden Unterstützung für die Koroutinen von Kotlin.
Dieses Projekt ist Teil des Eclipse-Ökosystems. Eine Vielzahl von Versionen und Optionen bieten viel Freiheit. Der Vert.x-Anwendungsgenerator zum Beispiel erzeugt entweder Java- oder Kotlin-Code mit Dutzenden von möglichen Abhängigkeiten wie Template-Engines oder API-Unterstützung.
Eclipse MicroProfile
Das Eclipse-Team hat das MicroProfile-Projekt ins Leben gerufen, um Jakarta EE für den Betrieb kleinerer Konstellationen von Microservices anzupassen. Es entfernt einen Teil des Overheads der größeren Plattform und bündelt gleichzeitig Bibliotheken, die für viele Microservice-Architekturen so gut wie Standard sind.
Der Ansatz ist vor allem für Entwickler attraktiv, die Code von größeren, älteren Java EE- oder Jakarta EE-Projekten migrieren. Ein Großteil der Konfiguration und Architektur bleibt gleich. In vielen Fällen sind die Anpassungen nur geringfügig. Aber das Design fördert die Art von Entscheidungen, die es einfacher machen, leichteren und schnelleren Code zu erstellen. Einige Entwickler nutzen MicroProfile als Sprungbrett auf dem Weg zu moderneren Cloud-nativen Frameworks.
Dropwizard
Einige Entwickler haben eine natürliche Vorliebe für ältere, gut getestete Module, und diese werden Dropwizard lieben. Das Dropwizard-Entwicklungsteam hat schon immer auf Worte wie stabil und erprobt Wert gelegt. Sie haben Module für Datenbankanbindungen wie Hibernate gesammelt und Frameworks für Formulare und andere Standard-Webanwendungskomponenten beigemischt.
Dropwizard ist ein Favorit für Teams, die an der Überarbeitung und Erweiterung einer bestehenden Anwendung arbeiten. Die Struktur ist mit älteren, etablierten Ansätzen kompatibel, da sie auf eben diesen aufbaut.
Starter-Frameworks für Cloud-Plattformen
Manchmal ist es nicht nötig, etwas Komplexes oder Aufwändiges zu schreiben. Alle Clouds enthalten grundlegende Beispiele, die sich gut für den Einstieg in das Schreiben einfacher Funktionen eignen. Sie sind hauptsächlich dazu gedacht, sehr einfache Lösungen zu unterstützen und Entwicklern einen schnellen Einstieg zu ermöglichen.
Das Entwicklungsteam von Google Cloud Platform hat beispielsweise sein Basis-Framework für Java-Funktionen, die in seinem Function-as-a-Service (FaaS) ausgeführt werden, als Open Source veröffentlicht. Der damit erstellte Code soll sich schnell in die Standard-Trigger von GCP integrieren lassen, obwohl er auch auf jedem lokalen Rechner erfolgreich ausgeführt werden kann.
Microsoft hat sein Framework auch als Open Source für Java zur Verfügung gestellt. Das Modell umfasst mehrere Routinen zur Vereinfachung von Datenübertragungen wie eine Bibliothek zur Übersetzung von JSON-Daten in und aus Java-POJOs. Wenn der Funktionsauslöser mit dem Aufruf Metadaten liefert, werden diese direkt vom Framework verarbeitet.
Mit diesen beiden Frameworks können Sie viele einfache Aufgaben erledigen, indem Sie nur eine einzige Klasse mit einer einzigen Funktion schreiben. Bei komplizierteren Projekten kann es sinnvoll sein, dieses grundlegende Werkzeug mit einigen der anderen beschriebenen Frameworks zu kombinieren. Dies sind zwar nur Ausgangspunkte, aber manchmal ist das auch schon genug.
*Peter Wayner schreibt unter anderem für unsere US-Schwesterpublikation InfoWorld.com und ist Autor verschiedener Bücher – unter anderem zu den Themen Open Source Software, autonomes Fahren und digitale Transaktionen.
Be the first to comment