d12g

Blog von Daniel Grewing

Minikompendium zum Thema Microservices

26. Juli 2015 Softwareentwicklung, Systemadministration

Neues zum Thema Microservices: Martin Fowler hat eine Art Minikompendium über Microservices erstellt.
Dieses ist unterteilt in die folgenden vier Bereiche:

Was sind Microservices?
Sehr kurz, aber prägnant beschreibt Fowler Microservices anhand ihrer Eigenschaften. Diverse Verlinkungen geben dann einen genaueren Einblick in das Thema.

Wann sollte ich sie nutzen?
Ob man diesen Architekturstil einsetzen möchte hängt natürlich auch immer von den aktuellen Anforderungen ab. Fowler beschreibt Vor- und Nachteile und zieht Vergleiche mit dem monolithischen Ansatz.

Wie erstellt man Microservices?
Dieser Bereich ist eine Linksammlung auf ein Buch und diversen Beiträgen und Vorträgen.

Wer nutzt sie?
Hier findet man Informationen zu den Vorreitern des Architekturstils: Netflix, Amazon und Google. Sehr interessant ist ein Beitrag der REA Group, einer australischen Firma in der Immobilienbranche. Die Firma teilt ihre Erfahrungen bei der Umstellung eines monolithischen Systems auf Microservices.

Linksammlung Microservices

5. Juli 2015 Softwareentwicklung

In meinen letzten Blogbeiträgen habe ich mich viel mit Microservices beschäftigt. Für mich immer noch ein sehr interessantes Thema, vor allem bei der praktischen Umsetzung. Die folgenden Seiten haben wir beim Einstieg sehr geholfen.

Für mich im Moment die Referenz in dieser Thematik: Martin Fowler hat schon einige Artikel zu Microservices geschrieben. Ich sehe ihn schon als Verfechter dieser Architektur, seine Betrachtungsweise ist aber dennoch immer differenziert und kritisch. Wem seine Artikel zu lang oder komplex sind, im JAXenter werden seine Beiträge regelmäßig zusammengefasst.

microservices.io beschreibt die Microservice Architektur aus der Sicht von Patterns. Neben den Microservices werden auch der monolithische Ansatz beschrieben und Lösungen für das Deployment (Veröffentlichung der Komponenten auf eine VM oder einen Container).

Für einen deutschsprachigen Einstieg kann ich einen Artikel auf Heise Developer empfehlen.

Einen kritischen Standpunkt habe ich auf dem Blog von Ralf Westphal gefunden. Interessant finde ich vor allem die Bezüge auf frühere Trends in der Software Entwicklung.

Replikation von Microservices

21. Juni 2015 Softwareentwicklung

Der Artikel Microservices – die am häufigsten gestellten Fragen auf jaxenter beschreibt viele Herausforderungen, die man sich stellen muss, aber auch, welche Vorteile man durch eine Microservice-Architektur erreicht.

Mir stellt sich zum Thema „Service Replication“ eine Frage, die ich mir noch nicht beantworten kann. Microservices zeichnen sich dadurch aus, dass sie alle Softwareschichten abdecken, von der GUI, der Business-Logik und der Persistenzschicht. Entwicklerteams sollen frei in der Wahl der eingesetzten Technologien sein. Eine mögliche Wahl wäre die Entwicklung einer Webanwendung, die auf einem Tomcat läuft und Zugriff auf eine relationale Datenbank hat, wie MySQL oder PostgreSQL.
ms4

Nicht alle Unternehmen stellen ihre Dienste bei Anbietern wie Amazons AWS bereit, sondern betreiben eigene Server und virtualisieren diese. Den hier beschriebenen Service auf einer virtuellen Maschine bereitzustellen ist für den Betrieb sicher keine hohe Herausforderung. Wenn die Anforderungen an den Microservice steigen, muss dieser skaliert werden können. Der Artikel beschreibt dazu die mögliche Skalierung auf der X-Achse. Bei meinem Beispiel würde das bedeuten, der VM weitere Ressourcen wie CPU oder RAM bereitzustellen.
Steigen nun aber die Anforderungen bezüglich der Verfügbarkeit ist eine Option den Microservice zu replizieren.
Im Artikel wird gesagt, dass eine Service Replikation leicht und basierend auf Metadaten erfolgen können sollte. Der Tomcat ist in einem Clusterverbund hinter einem Apache oder nginx leicht zu replizieren. Aber für mich besteht nun eine große Herausforderung darin, die relationale Datenbank in einem Clusterverbund zu betreiben. Den MySql- oder PostgreSql-Server als einen Master-Slave Verbund zu konfigurieren ist noch eine gängige Lösung. Wenn man also den Schritt von einer Instanz auf zwei Instanzen bewältigt hat, sind weitere Slave-Server einfach hinzufügt. Was ist aber, wenn man den Microservice in einer hochverfügbaren Umgebung betreiben möchte. Diese Datenbanksysteme in einem Clusterverbund zu betreiben, bei dem die Daten auch nach dem Ausfall einer oder mehrerer Nodes noch zur Verfügung stehen, ist schon eine sehr große Herausforderung, oder?
ms2

Zur Zeit würde ich wohl noch folgende Architektur dazu aufbauen. Man “zerpflückt” den Microservice noch weiter und betrachtet ihn nur auf der Ebene des Tomcats. Dieser wird dann in ein bestehendes Netzwerk hinzugefügt. Dort befindet sich bereits ein Apache-Cluster, der sich mittels mod_jk um die Lastverteilung auf die Tomcats kümmert. Zusätzlich steht ein Datenbankcluster zur Verfügung, auf dem auch andere, bestehende Microservices ihre Daten speichern. Dieser Aufbau lehnt sich also an das Shared Data Microservice Design Pattern.
ms5

Diskussion um MonolithFirst

13. Juni 2015 Softwareentwicklung

Für eine nähere Beschäftigung mit dem Thema Microservices ist es sehr interessant, den Meinungsaustausch zwischen Martin Fowler und Stefan Tilkov bezüglich einer “MonolithFirst”-Strategie zu verfolgen. Martin Fowler versucht in seinem Beitrag MonolithFirst darzustellen, dass es nicht immer sinnvoll sei, ein neues Projekt mit einer Microservice Architektur zu beginnen. Stefan Tilkov widerspricht diesem Ansatz und meint, wenn das Ziel eines neuen Projekts eine Microservice Architektur sei, sollte man nicht mit einem Monolithen starten.

Eine Zusammenfassung beider Meinungen kann man auch auf jaxcenter.de zu nachlesen:
Sind Monolithe besser als ihr Ruf? Wider die Microservices: Monolithe als Fundament

Stefan Tilkov antwortet auf Martin Fowler: Brauchst du Microservices, bau dir Microservices!

Pattern für Microservice-Architekturen

7. Juni 2015 Softwareentwicklung

Arun Gupta beschreibt in seinem Beitrag Microservice Design Patterns sechs verschiedene Pattern zum Aufbau einer Microservice Architektur. Verschiedene Ansätze zu kennen und vergleichen zu können ist sehr hilfreich, wenn man überlegt diesen Architekturstil anzuwenden. Er unterscheidet dabei auch, ob ein Projekt auf “der grünen Wiese” geplant werden kann oder ob eine bestehende monolithische Anwendung in Microservices zerlegt werden soll.

Aggregator Microservice Design Pattern
Dieser Ansatz wird als der gängigste beschrieben. In einen einfachem Beispiel greift eine Webseite (Aggregator) auf REST-Services zu, sammelt die erforderlichen Daten mit Hilfe der Komponenten zusammen und stellt diese anschließend dar. Eine erweiterte Form wäre, wenn selbst der Aggregator keine Benutzerschnittstelle implementiert hätte, sondern die Daten über REST-Services einliest, sie mit einer Businesslogik verarbeitet und dann selbst als REST-Service zur Verfügung stellt.

Proxy Microservice Design Pattern
Der Proxy ist eine Variation des Aggregator Pattern. Anstatt die Daten selber zu sammeln, werden die Anfragen an verschiedene Microservices weitergeleitet und dort verarbeitet. Gupta unterscheidet nach dem dumb proxy, der nur weiterleitet, und dem smart proxy, der ebenfalls einfache Business Logik verarbeitet.

Chained Microservice Design Pattern
Eine weitere Variante ist die Verknüpfung von Microservices in einer Kette, welche die requests vom Client von Service zu Service weiterleitet und die responses wieder in dieser Kette zurückgeleitet werden. Der Client ist solange geblockt bis die Kette komplett durchgearbeitet wurde. Welche Blockmechanismen die Services untereinander einsetzen spielt keine Rolle.

Branch Microservice Design Pattern
Dieses Pattern erweitert den Aggregator Ansatz um das Chained Microservice Design Pattern. Dabei kann der Aggregator verschiedene chains-Services synchron aufrufen.

Shared Data Microservices Design Pattern
Ein Prinzip beim Einsatz von Microservices ist, dass alle Schichten einer Anwendung von einer Komponente implementiert werden. Dieses Pattern ist eine Lösung dafür, dass eine monolithische Anwendung, die auf eine SQL-Datenbank zugreift, nicht einfach in unterschiedliche Komponenten zerlegt werden kann und alle ihre eigene Persistenzschicht mitführen. Der Ansatz beschreibt, wie Microservices auf eine Datenquelle zugreifen und diese als Datenschnittstelle fungiert. Dabei erhöht man zwar die Kopplung der Komponenten, man hat aber einen Schritt weg von der monolithischen Architektur erreicht.

Asynchronouse Messaging Microservice Design Pattern
Dieses Pattern beschreibt wie Microservices nicht über REST-Services kommunizieren, sondern über eine Message Queue, die asynchron Daten verteilt. Gupta verweißt bei diesem Pattern noch auf den Artikel Coupling Versus Autonomy Microservices.

Microservices (Teil 2)

17. Mai 2015 Softwareentwicklung

In meinem letzten Beitrag habe ich eine Einführung in den Architekturstil der Microservices gegeben. Am Beispiel der Webanwendung “Zetteln” habe ich gezeigt, wie man eine Webanwendung in verschiedene Komponenten aufteilen kann und welche Vorteile sich dadurch ergeben. In diesem Beitrag möchte ich meine Idee der Kommunikation der Komponenten untereinander anhand von Codebeispielen vorstellen.

Die Anmeldemaske von Zetteln wird mit einer einfachen HTML-Seite umgesetzt.

<form class="form-signin" id= "loginform">
  <h2 class= "form-signin-heading">Anmelden </h2>
  <div class= "alert alert-danger" role ="alert" style=" display: none;" id="alert_login_error" >
    Logindaten nicht korrekt
  </ div>
  <label for= "inputEmail" class ="sr-only"> E-Mail</ label>
  <input type= "email" id ="inputEmail" class= "form-control" placeholder="Email address" required autofocus>
  <label for= "inputPassword" class ="sr-only"> Passwort</label >
  <input type= "password" id ="inputPassword" class= "form-control" placeholder="Password" required>
  <button class= "btn btn-lg btn-primary btn-block" type="button" id="loginsubmit" >Login </button>
</form >

Die Überprüfung der Anmeldedaten wird von einer jQuery-Funktion ausgelöst. Da die jQuery-Funktion einen Ajax-Request auf eine andere Webanwendung durchführt, muss über ein Callback mit JSONP gearbeitet werden, damit keine Cross-Seite Exception von JavaScript ausgelöst wird.

$("#loginsubmit").click( function(){
  $.ajax({
    type: 'GET',
    url: 'http://localhost:8090/login',
    data: "email="+$("#inputEmail" ).val()+"&password=" +$("#inputPassword" ).val(),
    dataType: 'jsonp',
    success: function(responseData, textStatus, jqXHR){
      var uuid = responseData.uuid;
      if (uuid != '' ){
        location.href= "http://localhost:8088/zetteln/index/login?uuid=" +uuid;
      }
      else{
        $( "#alert_login_error").show();
      }
    },
    error: function (responseData, textStatus, errorThrown){
      $( "#alert_login_error").show();
    }
  });
});

Über den Callback wird der Benutzer verifiziert. Die Daten werden von der Spring Boot Komponente überprüft und an den jQuery Aufruf zurückgegeben:

@RestController
@RequestMapping("/login" )
public class LoginController {
  @RequestMapping(method=RequestMethod.GET)
  public @ResponseBody String login(@RequestParam (value="email" ) String email, @RequestParam(value="password" ) String password, @RequestParam(value= "callback") String callback) {
    String returnValue = callback + "(" +checkUser(email, password)+")";
    return returnValue ;
  }

  private String checkUser(String email , String password){
    String uuid = "";
    if (email .equals("daniel.grewing@googlemail.com" ) && password.equals("zetteln" )){
      uuid = "89dda95851504c6eb9ae99b9270e438b" ;
    }
  return "{\"uuid\":\"" +uuid +"\"}" ;
  }
}

In der Methode checkUser erfolgt die eigentliche Abfrage der Benutzerdaten. Sie ist hier nur beispielhaft umgesetzt und würde sonst über eine Datenbankabfrage laufen.

Wenn die Login Komponente die Daten verifiziert hat erfolgt die Weiterleitung zur eigentlichen Zetteln-Anwendung mittels location.href. Die Benutzerdaten können dann nochmal verifiziert werden.

Diese Codebeispiele zeigen die Kommunikation der drei Komponenten meiner kleinen Anwendung in einer Microservice-Architektur nur anssatzweise. Über das Thema Sichheit müsste ich mir nochmal einigen Gedanken machen und diese umsetzen.

Microservices

10. Mai 2015 Softwareentwicklung

Ein TOP-Thema in der Webentwicklung in den letzten Monaten ist der Architekturansatz der Microservices. Dieser Ansatz ist vergleichbar mit Ideen der Service-orientierten Architektur und des Domain-Driven Designs. In der konkreten Umsetzung werden oft Technologien wie Docker, node.js oder Spring Boot genannt. Einen vielbeachteten Artikel zu diesem Thema haben Martin Fowler und James Lewis geschrieben. Sie beschreiben sehr umfassend die Merkmale und Vorteile dieser Architektur.

Ich möchte dieses Thema in meinem Blog aufgreifen und anhand eines Beispiels näher erklären.
In der Webentwicklung kann man Microservices als einen Ansatz verstehen, wie man komplexe Webanwendungen als eigene Komponenten betrachtet. In der Business Technology nennt Eberhard Wolff das Gegenstück der Microservice Architektur: Den Deployment-Monolithen. Das sind Anwendungen, die viele verschiedenen Services und Funktionalitäten implementiert haben und bei Änderungen als Ganzes ausgeliefert werden. Microservices dagegen sind Komponenten, die Funktionalitäten eines Gesamtsystems abbilden, getrennt voneinander entwickelt und ausgeliefert werden. Jeder Microservice bildet dazu alle Schichten ab, von der Geschäftslogik, der Datenhaltung bis zur Benutzerschnittstelle. Miteinander kommunizieren die Microservices über Schnittstellen wie z.B. WebServices.
Dieser Ansatz bietet verschiedene Vorteile: Teams, die Microservices umsetzen, sind frei in der Wahl ihrer Technologie und können selbstständig Anforderungen umsetzen. Bei der Auslieferung werden neue Funktionalitäten schneller bereitgestellt, weil nicht ein komplexes Gesamtsystem deployed werden muss, sondern nur einzelne Komponenten. Netflix gilt in diesem Bereich als Vorreiter. Der Streaming Anbieter betreibt seine Microservices in der Amazon Cloud. In ihrem Tech-Blog schreiben sie über die Herausforderungen, Ansätze bei der Entwicklung und des Monitoring der über 100 Komponenten. Viele ihrer Lösungen geben sie als OpenSource Software an die Community weiter.

Da ich bisher eher theoretische Ansätze gelesen habe, habe ich mich diesem Thema anhand eines Beispiel genähert. Dazu habe ich als Idee eine Webanwendung, die man als Mischung aus Evernote, Google Keep und den Zettelkasten betrachten kann. Ich nenne sie Zetteln und sie ist eine einfache Notizverwaltung, die Notizen aus der Sicht eines “Zettels” betrachtet und diese miteinander in Beziehung setzt.

Die Wireframes skizzieren die Idee: Eine Landingpage enthält ein Login- und Registrierungsformular, sowie einige statische Seiten wie z.B. das Impressum. Nach dem Login erhält man Zugang zur Anwendung, die eine Übersicht über die gespeicherten Zettel zeigt. Über die Toolbar kann die Ansicht geändert und weitere Zettel hinzufügt werden.
Startseite
App
Edit

Da es sich es um eine kleine Anwendung handelt spricht wenig dagegen, sie z.B. als eine Grails-Anwendung umzusetzen. Deployment-Monolith ist für diese Anwendung sicher noch nicht der passende Ausdruck. Betrachtet man das aber mal aus dieser Perspektive ergeben sich bei der Auslieferung einer Grails Anwendung bereits einige Nachteile. Wenn ich nur auf der Startseite Textergänzungen oder Suchmaschinenoptimierungen vornehmen möchte, muss ich das in meiner Grails-Anwendung ändern und dieses als war-File neu auf dem Tomcat deployen. Ähnlich verhält es sich, wenn ich größere Änderungen in der Anwendung vornehme. Während dieser Zeit könnte auch die Startseite offline sein.

Um nun den Ansatz der Microservice-Architektur umzusetzen, kann man die Anwendung ist drei Komponenten aufteilen:
– Eine statische Webseite als Landing Page mit weiteren Unterseiten: Zetteln-Static
– Eine Spring Boot Anwendung, die als WebService die Registrierung und das Login übernimmt: Login
– eine Grails Anwendung, die die Zettelverwaltung umsetzt: Zetteln-App
MS-Architektur

In einem nächsten Blogbeitrag zeige ich beispielhaft, wie man diese Architektur mittels jQuery, Spring Boot und Grails umsetzen kann.