Java EE trifft Microservices: Elefant im Porzellanladen?

Lars Röwekamp

© iStockphoto.com/meseontour

In der Enterprise-Community hält sich hartnäckig das Gerücht, dass Java EE nicht wirklich als Werkzeug für die neue Wunderwelt der Microservices geeignet sei. Die Wurzeln des Enterprise-Java-Standards sind jedoch genau dort zu finden, wo wir heute mit dem Architekturansatz der Microservices hin wollen – in stark verteilten, fachlich orientierten Systemen. Warum also hat Java EE, in Bezug auf Microservices, einen so schlechten Ruf? Und ist er gerechtfertigt?

Unabhängig von den vielen Charakteristika, die eine Microservice-basierte Architektur im Detail auszeichnet, stehen vor allem die erhöhte Flexibilität bei Entwicklung und Deployment im Fokus. Etwas managementtauglicher könnte man es auch als „Time-to-Market-Optimierung“ bezeichnen. Leider scheint genau dieses „Time-to-Market“, selbst im Zeitalter von agiler Entwicklung und deutlich kürzeren Releasezyklen als noch vor Jahren, nicht wirklich zu Java EE zu passen. Dabei hebt bereits die erste J2EE-Spezifikation vor mehr als zehn Jahren hervor, dass Enterprise Developer sich zukünftig – dank J2EE – voll und ganz auf die Fachlichkeit der umzusetzenden Anwendung konzentrieren können, anstatt ihre Zeit mit der Lösung von Infrastrukturproblemen zu vergeuden. Zum ersten Mal rückt damals der Aspekt „Time to Market“ als Wettbewerbsvorteil für Anwender des Java-EE-Frameworks in den Fokus. Und auch der Begriff Enterprise Services taucht in der Spezifikation mehrfach auf: „The Java 2 Platform, Enterprise Edition reduces the cost and complexity of developing multitier, enterprise services. J2EE applications can be rapidly deployed and easily enhanced as the enterprise responds to competitive pressures.“

DevOps Docker Camp 2017

Das neue DevOps Docker Camp – mit Erkan Yanar

Lernen Sie die Konzepte von Docker und die darauf aufbauende Infrastrukturen umfassend kennen. Bauen Sie Schritt für Schritt eine eigene Infrastruktur für und mit Docker auf!

Woran liegt es also, dass Java EE den damaligen Ansprüchen nicht gerecht werden konnte und man sich als Java-EE-Entwickler im Kreise der Microservices-Fans wie ein Elefant im Porzellanladen fühlt?

Das Java-EE-Framework wird per Definition im Enterprise-Umfeld, somit also in großen Projekten eingesetzt. Derartige Projekte sind historisch bedingt häufig mit entsprechend komplexen Organisations- und Kommunikationsstrukturen versehen. Spätestens seit Conway’s Law wissen wir, dass diese Strukturen automatisch zu unnötig aufgeblähten Systemen führen, die nur wenig – sehr wenig – Flexibilität mit sich bringen: „Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization‘s communication structure.“

Aus dem eben aufgezeigten Betrachtungswinkel muss den Java-EE-Kontrahenten also zunächst einmal Recht gegeben werden. Die Frage, die sich an dieser Stelle allerdings stellt, ist, ob das beschriebene Szenario tatsächlich ein Problem von Java EE beschreibt oder eher ein Problem der Zeit, in der Java EE groß geworden ist. Eine Zeit, in der wir uns damit arrangiert hatten, dass Architekten schichtenbasierte Frameworks oder Generatoren inklusive eigener DSLs bauten, anstatt sich um fachliche getriebene Modularisierung oder fachliche Basiskomponenten zu kümmern. Eine Zeit, in der die einzelnen Teams sich mit ihren jeweiligen Spezialisten in der Regel eher an den verschiedenen Architekturschichten – wie User Interface, Businesslogik und Persistenz – orientierten, anstatt sich „cross-functional“ und somit an der gegebenen Fachlichkeit orientiert aufzustellen.

Abb. 1: Die schnelle „Time to Market“ von Microservices scheint nicht wirklich zu Java EE zu passen

Abb. 1: Die schnelle „Time to Market“ von Microservices scheint nicht wirklich zu Java EE zu passen

Ausgereifte Technologie

Betrachtet man einmal nur die Technologie und die APIs von Java EE, so ist es schon ein wenig verwunderlich, dass Java EE nicht für die Entwicklung von Microservices geeignet sein soll. Gehen wir davon aus, dass ein Microservice eine in sich geschlossene Fachlichkeit abbildet – auch bekannt als Bounded Context. Dieser bedient sich anderer Fachlichkeit via (RESTful) Web Services oder stellt anderen Services ihre Fachlichkeit zur Verfügung. Dann bringt Java EE mit CDI, JAX-RS, JPA und Co. alles mit, was notwendig ist, um einen solchen Service zu realisieren. Soll statt einer relationalen Datenbank eine NoSQL-Datenquelle verwendet werden, steht auch dem nichts im Wege, dank entsprechender Libraries. Und auch, wenn der Service sein eigenes, JavaScript-Framework-basiertes HTML 5 UI enthält – z. B. auf Basis des React-Frameworks oder AngularJS –, lässt sich dies problemlos realisieren.

Ein solcher Service muss dabei übrigens nicht automatisch, nur weil Java EE verwendet wird, eine „overengineered“ Mehrschichtarchitektur mit sich bringen, deren einziger Zweck es ist, via Dependency Injection die Infrastruktur der jeweils nächsten von zehn Schichten zu injecten, nur um so den gewünschten Methodenaufruf Schicht für Schicht weiter nach unten zu delegieren. Ganz im Gegenteil: Durch die gezielte Verwendung der CDI-Features zur fachlichen Injektion lassen sich extrem effiziente und schlanke Architektur realisieren, wie das folgende Beispiel eines Service aus einem Onlineshop verdeutlicht (Listings 1 und 2).

@Path("recommendations")
@Produces({MediaType.APPLICATION_JSON})
public class RecommendationResource {

  // inject book recommendations from corresponding producer
  @Inject @Book
  private List<BookRecommendation> bookRecommendations;

// inject music recommendations from corresponding producer
  @Inject @Music
  private List<MusicRecommendation> musicRecommendations;

  // inject video recommendations from corresponding producer
  @Inject @Video
  private List<VideoRecommendation> videoRecommendations;

  // inject common recommendations from corresponding producer
@Inject @All
  private List<Recommendation> allRecommendations;

  /**
   * Retrieves all {@code Recommendation} corresponding to a given type.
   *
   * @param recommendationType Type of the requested {@code Recommendation}
   * @return JAX-RS response
 */
  @GET
  @Path("/")
  public Response getRecommendationsFor(@DefaultValue("All")
    @QueryParam("recommendationType") String recommendationType) {

      List<? extends Recommendation> recommendations;

  switch (recommendationType) {
    case BOOK:
        recommendations = bookRecommendations;
        break;
    case MUSIC:
        recommendations = musicRecommendations;
        break;
    case VIDEO:
        recommendations = videoRecommendations;
        break;
    default: // use default and deliver recommendation of all types
        recommendations = allRecommendations;
      }

      if (recommendations.isEmpty()) {
        return Response
          .status(Response.Status.NO_CONTENT)
          .entity(Collections.<Recommendation>emptyList())
          .build();
      } else {
        return Response.ok()
          .entity(recommendations)
          .build();
      }
  }
}
@ApplicationScoped
public class RecommendationRepository implements Serializable {

@PersistenceContext
  private EntityManager em;

// produces book recommendations for current shop user
  @Produces @Book
  private List<BookRecommendation> getBookRecommendations(Principal currentUser) {
    return em.createNamedQuery(BookRecommendation.FIND_BY_USERNAME, BookRecomendation.class)
      .setParameter("username", currentUser.getName())
      .getResultList();
}

  // produces music recommendations for current shop user
  @Produces @Music
private List<MusicRecommendation> getMusicRecommendations(Principal user) {
    return em.createNamedQuery(MusicRecommendation.FIND_BY_USERNAME, MusicRecomendation.class)
      .setParameter("username", user.getName())
      .getResultList();
}

  // produces video recommendations for current shop user
  @Produces @Video
  private List<VideoRecommendation> getVideoRecommendations(Principal user) {
    return em.createNamedQuery(VideoRecommendation.FIND_BY_USERNAME, VideoRecomendation.class)
      .setParameter("username", user.getName())
      .getResultList();
}

  // produces common recommendations for current shop user
  @Produces @All
  private List<Recommendation> getAllRecommendations(Principal currentUser) {
    return em.createNamedQuery(Recommendation.FIND_BY_USERNAME, Recomendation.class)
      .setParameter("username", currentUser.getName())
      .getResultList();
}

}

Das Beispiel zeigt eine einfache REST-Ressource namens RecommendationResource (Listing 1), die für einen Onlineshop Kaufvorschläge zu verschiedenen Artikelkategorien liefert. Die Ressource lässt sich die gewünschten fachlichen Objekte via @Inject @Book List<Recommendation>, @Inject @Music List<Recommendation> und @Inject @Movie List<Recommendation> direkt injizieren, um sie dann in Form eines HTTP Responses an den anfragenden Client auszugeben.

Das Einbinden von Infrastrukturkomponenten aus den Zwischenschichten und das damit verbundene, schichtweise Delegieren von fachlichen Methodenaufrufen innerhalb dieser Komponenten bleibt der Ressource dank fachlicher Injektion erspart. Der Quellcode der Ressource spiegelt genau die Fachlichkeit wider, die implementiert werden soll, und nicht die zugrundeliegende Architektur, was zu einem deutlich besser lesbaren Codes führt.

Das Gegenstück zu den oben skizzierten Injection Points stellen entsprechende Producer-Methoden innerhalb der Klasse RecommendationRepository (Listing 2) dar. Das Repository stellt die angefragten fachlichen Objekte via CDI Producer für den jeweiligen Request zur Verfügung, wobei die verwendeten CDI Qualifier @Book, @Music und @Movie dazu dienen, die unterschiedlichen Kaufvorschläge fachlich zu qualifizieren und somit voneinander abzugrenzen.

Zur Personalisierung der Trefferliste lässt sich das Repository übrigens den aktuellen Shopkunden in Form der aktuellen Java-Securiry-Principal-Instanz via @Inject Principal currentShopCustomer injizieren. Diese wird im Vorfeld via OAuth2-Token evaluiert und für den aktuellen Request gesetzt.

Wie das Beispiel zeigt, spricht aus rein technologischer Sicht nichts gegen die Verwendung von Java EE zur Realisierung von Microservices. Warum also nicht anstelle eines fetten Monolithen einfach eine Reihe von Microservices implementieren und diese als einzelne WARs auf einem Application Server deployen? Java EE mit seinen APIs bietet alles, was man dazu braucht – und darüber hinaus noch vieles mehr. Oder ist eventuell genau das das Problem?

Ein Schwergewicht namens App Server

Gehen wir noch einmal einen Schritt zurück und schauen uns die Umschreibung von Microservices von Martin Fowler an (siehe Kasten). Fowler spricht in seiner Definition von Applikationen, die sich aus einer Reihe von kleinen Services zusammensetzen, die in eigenen Prozessen laufen und mittels leichtgewichtigen Mechanismen kommunizieren. Diese Services sollen unabhängig deploy- und skalierbar sein, sich fachlich eindeutig von den anderen Services abgrenzen und von verschiedenen Teams gemanagt werden können. Zieht man zusätzlich noch das Zitat des Amazon-AWS-Managers Rob Brigham heran (ebenfalls im Kasten zu finden), so wird schnell klar, dass das eigentliche Problem nicht in der zu verwendenden Technologie, sondern in dem Grad der möglichen Automatisierung des Software Development Lifecycle (SDLC) für einen einzelnen Service und somit in der Minimierung des Overheads für das verantwortliche Team liegt.

Es gilt also, Java EE weniger als Technologie zu betrachten als vielmehr den Application Server sowie die Möglichkeiten zum Development, Build, Deployment, Management und Monitoring von Artefakten, die in ihm leben.

Das De-facto-Standardvorgehen für Build und Deployment sieht für Java-EE-Anwendungen vor, dass die einzelnen Komponenten – in unserem Beispiel also der Recommendation Service – in einem EAR oder WAR zusammengepackt und dann auf einem Server deployt werden. Skalierung wird über das Hinzunehmen weiterer App-Server-Instanzen und die Partitionierung der Datenbank erreicht – zum Beispiel aufgeteilt nach Mandanten. Eine Skalierung nach der tatsächlich anfallenden Last pro Fachlichkeit oder Use Case kann bei diesem Vorgehen nur erreicht werden, wenn jede Fachlichkeit – also jeder Service – als eigenes WAR auf einer eigenen Serverinstanz deployt werden würde [1].

Stellen wir uns nun einen auf Microservice basierenden Webdienst wie Amazon oder Netflix vor, dann sprechen wir hier über einige tausend Serverinstanzen mit abertausenden Deployments pro Jahr – Amazon rühmt sich sogar mit einer Zahl von etlichen Millionen Deployments! Spätestens an dieser Stelle ist es auch für den größten Java-EE-Verfechter nur schwer vorstellbar, dass unsere guten alten Schlachtschiffe Websphere, WebLogic, JBoss oder Glassfish dies bewerkstelligen können. Und auch bei den New Kids on the Block wie WildFly und TomEE kommen berechtigte Zweifel auf. So klein und schnell die Server in Bezug auf Startup-Zeiten in den letzten Jahren auch geworden sein mögen, dem eben skizzierten Szenario und den damit verbundenen Real-Life-Anforderungen halten sie nicht stand – insbesondere nicht in PaaS- (Cloud) oder Container-umgebungen (Rocket, Docker). Zu groß ist der durch den Java-EE-Standard diktierte Overhead an zu unterstützenden APIs und Runtime-Features.

Java EE auf Diät

Wie können wir also unsere in den letzten Jahren mit den Java-EE-APIs gesammelten Erfahrungen auch in Zukunft weiter nutzen und trotzdem aus der monolithischen Welt in die Wunderwelt der Microservices migrieren? Ganz einfach: Wir brauchen leichtgewichtige Server, die genau nur diejenigen Bestandteile von Java EE mit sich bringen, die wir für den jeweiligen Service benötigen – nicht mehr und nicht weniger. Wenn wir dann noch in die Lage versetzt werden, die von uns benötigten Bestandteile und Funktionalitäten des Servers in den Service einzubinden, anstatt den Service in dem Server zu deployen, dann haben wir unser Wunschszenario erreicht (Abb. 2).

Abb. 2: (Micro)Service vs. Server: Den Server in den Service einbinden, anstatt den Service in dem Server zu deployen

Abb. 2: (Micro)Service vs. Server: Den Server in den Service einbinden, anstatt den Service in dem Server zu deployen

Als Resultat erhalten wir einen Service, der sowohl seine Fachlichkeit als auch seine eigene Laufzeitumgebung mitbringt. Die Laufzeitumgebung ist dabei optimal auf die Anforderungen des jeweiligen Service angepasst, der Overhead entsprechend minimal. Schauen wir noch einmal auf unser Beispiel des Recommendation Service. Wir benötigen weder ein JSF-basiertes UI noch EJBs. Auch APIs wie JSP, JCA, JMS, WebSocket, Batch, JAX-WS oder XML Binding sind in unserem Kontext völlig überflüssig – also raus damit!

Einmal deployt und gestartet läuft unser Service – wie von Fowler gefordert – autark als eigener Prozess und kann so jederzeit eigenständig vom zuständigen Team gemanagt werden. Das ist insbesondere dann wichtig, wenn zur Verwaltung der vielen Services das Rad nicht neu erfunden wird, sondern auf etablierte Open-Source-Tools – z. B. aus dem Hause Netflix – zurückgegriffen werden soll. Denn die meisten dort zu findenden Tools sind nicht darauf ausgerichtet, Services in einem Server zu managen, sondern eigene Prozesse.

Man kann in diesem Kontext übrigens auch von einem Self-contained System sprechen, wobei dieser eher grobgranulare Ansatz nicht ganz deckungsgleich mit dem extrem feingranularen Microservice-Ansatz von Netflix und Co. ist. Die gute Nachricht: Es gibt bereits passende Lösungen am Markt – auch im Umfeld von Java EE.

Microservice Bootstraper: Das Baukastenprinzip

In den letzten Monaten bieten immer mehr Hersteller von Java-EE-Servern baukästenähnliche Lösungen an, die es erlauben, nur genau die Bestandteile mit dem Service zu deployen, die zur Laufzeit benötigt werden. Das Ganze als ausführbares JAR verpackt, um ein paar Schnittstellen zum Management, Monitoring und Alerting erweitert und in Docker installiert, erlaubt es dem zuständigen Microservice-Team Deployment- und Runtime-Verantwortung für seinen Service zu übernehmen. Welcome to the World of DevOps.

Das speziell auf hochperformante RESTful Services ausgelegte Java-Framework Dropwizard ist einer der Vorreiter, wenn es um Rundum-sorglos-Pakete für Java-(EE-)basierte Microservices geht. Dropwizard versucht mit seinen Bibliotheken und Tools, den gesamten Software Development Lifecycle eines Microservice abzudecken. So unterstützt Dropwizard nicht nur bei der Entwicklung und dem Deployment eines Microservice, sondern vor allem auch bei dessen Konfiguration, und erlaubt darüber hinaus – dank Metrics Library – das Erheben von anwendungsspezifischen Metriken. Das Team von Dropwizard setzt dabei bewusst auf etablierte Komponenten, wie die Servlet-Engine Jetty, die JAX-RS-Referenzimplementierung Jersey oder den JSON-Parser Jackson, um so den Entwicklern den Einstieg zu erleichtern und sich selbst auf die optimale Integration der verschiedenen Dropwizard-Bestandteile fokussieren zu können. Als Resultat des Build-Prozesses erhält man ein JAR mit eingebettetem Jetty-Server. Ein Bereitstellen des Service ist somit theoretisch durch ein einfaches Kopieren der Datei auf den Zielserver möglich. Natürlich kann das Ganze aber auch in einem Docker-Container bereitgestellt werden. Beim Start der Main-Methode wird eine eigene Jetty-Instanz gestartet. Fertig ist der maßgeschneiderte, Java-EE-basierte Microservice, der dank Metrics durch das zuständige Team zur Laufzeit bezüglich Health-Status und Performance überwacht werden kann.

Einen ähnlichen Ansatz wie Dropwizard verfolgt auch Wildfly Swarm. Im Gegensatz zu Dropwizard kann der Entwickler allerdings frei entscheiden, ob sein Service zu einem eigenen JAR werden (auch bekannt als ueberjar) oder aber als WAR in einem Java-EE-kompatiblen Server deployt werden soll. Diese ohne zusätzlichen Programmieraufwand gewonnene Flexibilität kann insbesondere in einem Migrationsszenario, in dem Schritt für Schritt einzelne Microservices aus einem Java-EE-Monolithen herausgelöst werden, von großem Nutzen sein. Als zusätzlichen Mehrwert bietet WildFly Swam eine gute Integration für Third-Party-Frameworks, die sich im Microservice-Umfeld etabliert haben, wie Logstash oder die Netflix-OSS-Projekte Hystrix und Ribbon. Wie nicht anders zu erwarten, ist auch eine Integration mit anderen Red-Hat-Projekten gewährleistet, wie KeyCloak (Single Sign-on), Hawkular (Monitoring), InfiniSpan (Data Grid) oder OpenShift (PaaS). WildFly Swarm ist aktuell zwar nur in der Version 1.0 Alpha 7 verfügbar und somit (noch) nicht zum produktiven Einsatz geeignet, hat aber auf jeden Fall das Zeug dazu, zukünftig ein wichtiger Player zu werden.

Natürlich darf an dieser Stelle auch der Java Duke’s Choice Award Winner von 2015 – KumuluzEE – nicht unerwähnt bleiben. Einmal abgesehen von dem Framework selbst, das eine Art „Best of“ verschiedener etablierter Open-Source-Lösungen der einzelnen Java-EE-APIs darstellt, fällt KumuluzEE besonders durch gute Dokumentation und Tutorials sowie ein mehrstufiges Supportprogramm ins Auge, das es einem Microservice-Projekt erlaubt, mit den Anforderungen zu wachsen.

Neben den bisher genannten Lösungen haben mit TomEE Shades und Payara Micro Glassfish (aktuelle Status: „experimental“) zwei weitere im Java-EE-Umfeld etablierte Anbieter den Schritt in Richtung Microservices gewagt und bieten entsprechend leichtgewichtige Lösungen für ihren Server zum Bootstrapen von Microservices an, die sich gemeinsam mit dem Service als ein JAR deployen lassen.

Und was ist mit Spring Boot? Auch wenn es auf den ersten Blick nicht unbedingt der nächstliegende Schritt für einen Java-EE-Entwickler sein mag, seine ersten Gehversuche im Microservice-Umfeld mit einem Spring-Tool zu unternehmen, so ist es zumindest ein denkbarer. Spring Boot ist ohne Frage etabliert und stabil. Und es gibt wahrscheinlich kaum eine andere Lösung am Markt, die einen so schnellen Einstieg in die servicebasierte Welt erlaubt und dabei gleichzeitig ein so umfangreiches Tooling zum Management und Monitoring mitbringt. Dies gilt insbesondere dann, wenn man Spring Boot im Zusammenspiel mit Spring Cloud verwendet und so eine direkte Integration mehrerer Netflix-OSS-Komponenten erhält. Seine wirkliche Stärke spielt Spring Boot natürlich erst dann aus, wenn man sich auch auf die vielen enthaltenen Spring APIs und die damit verbundenen Paradigmen einlässt. Spätestens in diesem Moment aber kehrt man der Java-EE-Welt und somit dem Enterprise-Java-Standard den Rücken.

Von Containern und Wolken

Natürlich müssen Microservices nicht zwingend immer gleich in einer Cloud deployt werden. Rufen wir uns aber ins Gedächtnis, dass wir durch den Microservice-basierten Ansatz unter anderem auch eine größtmögliche Flexibilität bezüglich Last und der damit verbundenen Kosten erreichen wollen. Dann drängt sich die Cloud als Serviceplattform nahezu auf. So wundert es auch nicht, dass bei der Zusammensetzung der Topics für Java EE 7 das Thema Cloud – in Form von PaaS- und Muliti-Tanancy-Support – ganz oben auf der Liste stand. Da die damals vorgeschlagenen Lösungsansätze aber alles andere als ausgereift waren, wurde das Topic zunächst auf Java EE 8 und somit auf frühestens Mitte 2017 verschoben. Ist das ein K. O.-Kriterium? Nein, denn wie bereits gezeigt, geht es weniger darum, ob der App-Server Cloud-fähig ist, als vielmehr darum, ob der Microservice mit seiner eingebetteter Runtime in der Cloud gemanagt werden kann.

Je nach Cloud-Lösung lassen sich die eben gezeigten Bootstraper mehr oder minder gut in der Cloud managen. Ausschlaggebend dabei ist, welche Infrastruktur die Cloud bereits von Haus aus zur Verfügung stellt und welche Integration von Third-Party-Tools die Bootstraper mitbringen. Um sicherzustellen, dass man keine bösen Überraschungen erlebt, bietet es sich an, Container wie Docker zur Virtualisierung zu verwenden. Dies gibt den Entwicklern zusätzlich die Möglichkeit, nicht nur den Java-EE-basierten Microservice selbst zu testen, sondern auch die zugehörige Infrastruktur inklusive aller Konfigurationen und Abhängigkeiten.

Fazit

Java EE bietet aus rein technologischer Sicht alles, was es zur Entwicklung von Microservices braucht. Trotzdem ist der Enterprise-Java-Standard für viele Microservice-Neueinsteiger nicht unbedingt die nächstliegende Wahl. Neben der eigentlichen Entwicklung ist vor allem die vollständige und effiziente Automatisierung sämtlicher Phasen des Software Development Lifecycles für eine erfolgreiche Einführung von Microservices von Belang. Und genau hier haben Java EE und die zugehörige Runtime klare Schwächen. Der Application Server ist einfach zu schwergewichtig, als dass tausende Instanzen permanent neu deployt werden könnten. Dies gilt nicht nur für die traditionsbehafteten Dinos am Markt, sondern auch für die auf das Web Profile ausgerichteten Leichtgewichte.

Die notwendige Automatisierung ist mit der gewünschten Effizienz nur dann realistisch, wenn die Server noch weiter abspecken. Nach dem Vorbild von Dropwizard und Spring Boot tauchen in den letzten Monaten daher vermehrt Lösungen auf, mit denen sich die eigene Java-EE-Anwendung oder der Java-EE-basierte Microservice mit genau den Bestandteilen bootstrapen lässt, die für den Service benötigt werden. Das Resultat sind schlanke, schnell deploybare Microservices auf Basis von Java EE. Dank guter Integration von im Microservice-Umfeld etablierten Open-Source-Lösungen à la Netflix OSS und Co. kommen dabei auch das Management und Monitoring der Microservices nicht zu kurz – sowohl auf dem eigenen Server als auch in der Cloud.

Es ist also mit Java EE durchaus möglich, neue Features in Form von fachlich orientierten Microservices mit hoher Qualität zu implementieren und schnell an den Markt zu bringen. Time-to-Market und Java EE müssen sich, richtig angegangen, nicht widersprechen, ganz im Gegenteil. Dank Standard kann auf jahrelang aufgebautes Fachwissen zurückgegriffen werden, zumindest dann, wenn die Java-EE-Entwickler bereit sind, den einen oder anderen alten Zopf abzuschneiden und sich auf neue, spannende Welten einzulassen. Denn, wie bereits zu Anfang angedeutet: Nicht Java EE ist das Problem, sondern die Zeit, in der das Framework groß geworden ist.

Microservices und Continuous Delivery

„A kind of Definition“ von Martin Fowler
„In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.“
„As well as the fact that services are independently deployable and scalable, each service also provides a firm module boundary, even allowing for different services to be written in different programming languages. They can also be managed by different teams.“
„Continous Delivery “ von Rob Brigham (Amazon AWS Senior Manager)
„For a company like Amazon that prides itself on efficiency — for a company that uses robots inside of our fulfillment centers to move around physical goods, a company that wants to deploy packages to your doorstep using drones – you can imagine how crazy it was that we were using humans to pass around these virtual bits in our software delivery process.“

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.
Kommentare

Schreibe einen Kommentar

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