Beiträge

Microservices, Load Balancing

Die Prüfung der Skalierbarkeit von Microservices war ein weiteres sehr wichtiges Thema in unserem Microservices Projekt. Im Rahmen unser dazugehörigen Blog Serie möchte ich hier das Thema Load Balancing im Kontext der Microservice Architektur näher beleuchten. Häufig werden im Bereich der Bibliothekssysteme zentrale Dienste, wie zum Beispiel ein zentrales Dokumentenmanagement wie Fedora oder eine zentrale Suche mit Solr oder Elasticsearch benötigt. In unserem Projekt wollten wir herausfinden, wie und mit welchem Aufwand Services dynamisch skaliert werden können. Dies bedeutet, dass in Situationen in welchen die Client Anwendungen durch die Nutzer der Bibliothek stark verwendet werden, die Services dynamisch auf zusätzliche Server installiert und anschließend verwendet werden. Dynamisch bedeutet an dieser Stelle automatisiert und damit ohne Administrations-, Konfigurations- bzw. Entwicklungsaufwand.

Wie in unserem ersten Beitrag beschrieben, bietet die Microservices Architektur unter anderem den Vorteil der einfacheren und genaueren Skalierung einzelner Microservices. Wird nun eine Softwarekomponente bzw. ein Service auf mehrere Server automatisiert installiert, müssen diese auch durch die Anwendungen genutzt werden können. Als Teil der „Platform Services“ bietet der Netflix Open Source Stack (Netflix OSS) auch hier eine sehr gute Lösung. Bevor ich die konkrete Lösung vorstelle, möchte ich noch etwas zur Theorie des Load Balancing sagen. Grundsätzlich gibt es zwei wesentliche Varianten um dieses aufzubauen.

 

Zentrales Load Balancing.

Dabei wird ein zentraler Load Balancer zwischen den Client Anwendungen und den Services aufgebaut. Alle Anfragen der Clients werden über den Load Balancer geroutet und dieser verteilt die Anfragen nach einem bestimmten Verfahren auf die einzelnen Service Instanzen. Ein Nachteil dieser Lösung ist, dass der Load Balancer ein Single Point of Failure ist. Dies bedeutet, dass wenn diese Komponente ausfällt bzw. stark überlastet ist, sie keine Anfragen mehr von den Anwendungen zu den Services weiterleitet.

Zentrales Load Balancing

Zentrales Load Balancing

Dezentrales Load Balancing

Hierbei hält die Client Anwendung alle Informationen, welche Service Instanzen verfügbar sind, bei sich lokal vor. Diese Informationen werden regelmäßig aktualisiert, sodass die aktuelle Situation der verfügbaren Services dem Client jederzeit bekannt ist. Die Client Anwendung entscheidet mit Hilfe eines eingebauten Load Balancing Mechanismus selbst, welche Service Instanz für eine Anfrage verwendet wird. Damit ist keine zentrale Load Balancer Instanz mehr notwendig und es gibt keinen Single Point of Failure. Auch bei dieser Lösung gibt es wiederum Nachteile, dass zum Beispiel die lokale Information, welche Instanzen der Services verfügbar sind, veraltet sein kann.

Dezentrales Load Balancing

Dezentrales Load Balancing

Die einzelnen Load Balancing Verfahren, nach welchem Algorithmus eine von mehreren verfügbaren Service Instanzen ausgewählt wird, möchte ich hier nicht aufführen, da es in diesem Beitrag um die Integration im Bereich der Microservices Architektur geht und nicht um das Load Balancing als solches. Der Netflix OSS bietet mit der Bibliothek Ribbon eine Möglichkeit des dezentralen, client-seitigem Load Balancing. Die Information, welche Service Instanzen auf welchem Server verfügbar sind, basieren auf den Informationen aus der Service Registry Eureka. Durch die Integration von Eureka ist das Load Balancing dynamisch und wird jederzeit an die verfügbaren Instanzen angepasst. Es ist auch möglich, Ribbon ohne Eureka einzusetzen, was hier aber nicht näher erläutert werden soll, da es für den produktiven Einsatz nicht empfohlen werden kann.

 

Unsere Erfahrungen

Die Integration von Ribbon in eine Client Anwendung ist einmal mit der Spring Cloud oder aber durch die Einbindung der nativen Netflix Bibliothek möglich. Bei beiden Varianten gibt es jeweils die Möglichkeit mittels direkter Verwendung eines Ribbon Clients das Load Balancing zu integrieren oder die Methode REST Templates zu definieren und zu verwenden. Beide Varianten unterscheiden sich vom Aufwand nicht. Elegant bei der Template Variante ist aus meiner Sicht die Trennung der Definition der zur Verfügung stehenden Funktionalität und deren Verwendung. So können zentral alle zur Verfügung stehenden Templates definiert und diese anschließend an den unterschiedlichsten Stellen eingesetzt werden. Dies vereinfacht die Wartung der bestehenden Möglichkeiten sehr stark. Allerdings konnten wir beim Einsatz des REST Templates für einen HTTP POST Request mit Multipart Upload nicht erfolgreich umsetzen. Beim Absetzen des HTTP POST Request wurde jeweils folgender Fehler gemeldet:

the request was rejected because no multipart boundary was found

Bisher haben wir noch keine Antwort zu unsere Anfrage nach einer Lösung aus der ribbon usergroup erhalten. Zusätzlich zur Integration im Quellcode muss das Load Balancing noch konfiguriert werden. Hier kann zum Beispiel auch zwischen den möglichen Verteilungsverfahren gewählt werden. Ribbon unterstützt zum Beispiel folgende:

  • RoundRobinRule
  • AvailabilityFilteringRule
  • WeightedResponseTimeRule

Alle Details zur Konfiguration von Ribbon können im Wiki des Projektes nachgelesen werden. Zusammenfassend können wir sagen, dass die Integration von Ribbon in eine Anwendung ohne großen Aufwand umzusetzen ist und sehr zuverlässig funktioniert. Bis auf die Ausnahme des HTTP POST Multipart Request sind wir auf keine weiteren Schwierigkeiten gestoßen.

 

Einsatz des Load Balancing

Unsere Client Anwendungen im Pilotprojekt bietet die Funktion eines Upload von XML Dateien. Diese lädt die Dateien nach der Auswahl im Browser via einer REST Schnittstelle in ein Dokumentenmanagementsystem (Microservice). In die Client Anwendungen haben wir das Load Balancing mit Hilfe der nativen Netflix Bibliothek integriert. In einem Test eines Ausfalls von einem der Dokumentenmanagement Services während des Uploads von 1000 XML Dateien konnten wir zeigen, dass der Upload nicht beeinträchtigt wird. Der Anwender bemerkt nicht, dass zu Beginn des Uploads noch zwei und während des Uploads nur noch eine Service Instanz des Dokumentenmanagement Services die Daten speichert. Ohne den Einsatz von Eureka und Ribbon wäre der Upload bei Ausfall des Dokumentenmanagement Services abgebrochen.

 

Fazit:

Auch für das Thema Load Balancing kann ich den Einsatz für zentrale Services in Kombination mit einer Service Registry nur stark empfehlen. Der Aufwand der Integration in eine Java Anwendung ist meines Erachtens eher gering und lohnt sich. Nach Abschluss der Integration können die Microservices einfach skaliert und die Client Anwendung kann so jederzeit stärker verwendet werden und reagiert robuster auf Ausfälle.

Microservices, Service Registry „Die Zentrale“

Im Rahmen unseres IT Projektes “Microservices” und der damit verbundenen Blog Serie möchte ich in diesem Beitrag über unserer Erfahrungen mit den „Platform Services“, welche ein zentraler Baustein in der Microservices Architektur sind, berichten. Es sind zusätzliche Dienste welche den Betrieb von zahlreichen Anwendungsservices vereinfachen. Dazu gehören unter anderem

Alle diese Dienste ermöglichen es eine große Anzahl an Microservices zu betreiben und nutzbar zu machen. Diese Auflistung sieht auf den ersten Blick nach sehr viel Aufwand und technischer Infrastruktur aus und beinhaltet Begrifflichkeiten, welche tiefgehendes, technisches Wissen erfordern um die Bedeutung und Notwendigkeit verstehen zu können. Aus diesem Grund möchte ich in den kommenden drei Beiträgen etwas Licht ins Dunkle bringen und versuchen den Mehrwert dieser technischen Services zu erläutern. Beginnen möchte ich mit der Service Registry, weil diese aus meiner Sicht die grundlegendste Komponente ist auf welcher viele der anderen Services aufsetzen.

 

Die Services Registry stellt in gewisser Weise eine Art Telefonzentrale dar , die Clientanwendung, wie zum Beispiel ein Content Management System oder aber eine andere beliebige Webanwendung, anrufen können um nach einem Dienst zufragen, welcher gerade benötigt wird. Tatsächlich fragt die aufrufende Anwendung mit einem Namen wie zum Beispiel: “Suche” oder “Dokumentenmanagement” die Service Registry und erhält die Information wie dieser Service zu erreichen ist. Die Information beinhaltet eine vollständige URL und kann als Einstiegspunkt zur Verwendung des Service benutzt werden.

 

Die einfachere und klassische Variante ohne die Verwendung einer Service Registry ist, dass die Client Anwendung die URL auf den Einstiegspunkt selber gespeichert hat. Allerdings gibt es bei dieser klassischen Variante einige Nachteile:

 

  • Die URL ist statisch in der Clientanwendung gepflegt und muss bei Veränderungen der URL mit geändert werden. Zieht der zu nutzende Service auf einen anderen Server um oder ändert sich der TCP/IP Port, muss die Clientanwendung in der Regel mit angepasst werden.
  • Es ist keine Verwendung von clientseitigem Load Balancing möglich. Das bedeutet, selbst wenn der Service auf mehreren Servern eingerichtet ist, kann der Client diese nicht dynamisch nutzen.
  • Es gibt oft keine Echtzeit Übersicht über den aktuellen Stand der zur Verfügung stehenden Services. Es besteht natürlich die Möglichkeit, ein sehr gutes Monitoring einzurichten, was diese Fähigkeit besitzt. Allerdings sind die klassischen Monitoring Lösungen wie zum Beispiel Nagios dafür nicht konzipiert und vorgesehen. In den meisten Fällen sind diese auch so nicht eingerichtet.

 

Diese aufgeführten Nachteile der herkömmlichen Verknüpfung von Clientanwendung und Anwendungsdienst (Service)  zeigen im Umkehrschluss natürlich auch die Vorteile einer Service Registry:

 

  • Zentrale Übersicht aller Service und deren Status
  • Möglichkeit eines Load balancing
  • Keine clientseitige Anpassung bei Service und Infrastruktur Änderungen

 

Aber rechtfertigen diese Vorteile den Aufwand und den Betrieb einer Service Registry? Der Aufwand der Installation einer Service Registry ist sehr gering, da es bereits sehr gute und ausgereifte Produkte gibt:

 

 

Die beiden erst genannten Produkte sind diejenigen mit der höchsten Verbreitung und damit auch die ausgereiftesten. In unserem Projekt haben wir hauptsächlich auf den Netflix OSS gesetzt und daher auf Eureka. Auch wir haben in unserem Pilotprojekt sehr gute Erfahrungen mit Eureka gemacht. Wichtig bei der Verwendung ist, dass die Service Registry nicht wiederum selbst zum Single Point of Failure wird und daher immer mehrfach betrieben werden sollte. Aber auch dieser Aspekt ist mit sehr geringem Aufwand umzusetzen. Ich empfehle für den Einstieg daher ein Spring Boot Projekt mit aktivierter Service Registry, welches im Beispiel Microservices Projekt von Eberhardt Wolff zur Verfügung steht. Sie werden erstaunt sein, mit wie wenig Quellcode die Service Registry umgesetzt ist.

Der Quellcode…

@SpringBootApplication
@EnableEurekaServer
@EnableDiscoveryClient
public class ServiceRegistryApplication {

public static void main(String[] args) {
SpringApplication.run(ServiceRegistryApplication.class, args);
}
}

 

Fazit:

Aus meiner persönlichen Sicht ist der Einsatz einer Service Registry auch ohne die Verwendung der gesamten Microservices Architektur von unschätzbarem Vorteil, sobald mehrere zentrale Services im Hause betrieben werden. Alleine die Tatsache, dass nicht mehr mit jeder Infrastruktur Anpassung die Client Anwendung und die Dokumentation bzw. das Monitoring angepasst werden müssen, sind im Dauerbetrieb mit geringem Personaleinsatz von unschätzbarem Wert. Hinzu kommt, dass wir in unserem Beispiel Projekt sowohl die Anbindung von Java Webanwendungen als auch von reinen HTML / Javascript Anwendungen relativ einfach umsetzen konnten. Wir konnten aus dem weit verbreiteten CMS Typo3 sehr leicht die Service Registry nach einem Service anfragen und diesen anschließend nutzen. Integriert man diese Anfrage Logik zum Beispiel in eine Typo3 Extension und macht diese so nachnutzbar für andere Typo3-Projekte, wird der Aufwand auf alle Projekte betrachtet noch geringer und der Nutzen somit noch größer. Zusätzlich bietet eine Service Registry als Basis der Platform Services weitere Möglichkeiten, welche ebenfalls von unschätzbarem Wert, um stabilen Betrieb von zentralen Services sind.

 

Diese Möglichkeiten werde ich in den kommenden Beiträgen detailliert aufführen und zeigen, wie man zum Beispiel ein bestehendes Fremdsystem, wie zum Beispiel Fedora Content Repository oder Pazpar2-Suche, in eine solche Service-Struktur einfach einbindet, ohne die Produkte selbst anpassen zu müssen.

Ich freue mich daher auf die kommenden Beiträge und hoffe auf zahlreiche Kommentare.

Microservice-Projektblog: Eierlegende Wollmilchsau

In der Abteilung Informations- und Datenmanagement der Staatsbibliothek zu Berlin (IDM) wird derzeit evaluiert, inwieweit das Architekturmuster„Microservices“ als Grundlage zukünftiger Eigenentwicklungen hilfreich sein können. In einer Reihe von Blogbeiträgen geben wir im Sinne eines Werkstattberichtes einen Einblick in das Projekt und unsere Erfahrungen mit der Umsetzung.

Der Auslöser unserer Neugier auf die relativ neue Technologie war die konkrete Aufgabe, dass ein Altsystem im Bereich der Nachweissysteme (Gesamtkatalog der Wiegendrucke) technisch modernisiert werden sollte. Soweit kein ungewöhnlicher Fall: in gewohnter Arbeitsweise wurde ein Team aus Entwicklern und einem fachliche Experten zusammengestellt. Eine Kleinigkeit war allerdings diesmal anders. Es gab neben den fachlichen Anforderungen – die Modernisierung des Nachweissystems zum Gesamtkatalog der Wiegendrucke – auch folgende nicht funktionalen Anforderungen:

  • Leichte Erweiterbarkeit des Systems
  • Testbarkeit
  • Hoher Grad an Wiederverwendungsmöglichkeiten
  • Skalierbarkeit

Mein erster Gedanke war: aha wir sollen also die „eierlegende Wollmilchsau“ entwickeln.

Der offensichtliche Grund für diese neuen Anforderungen war, dass in den letzten Jahren an der Staatsbibliothek im Rahmen von Projekten zwar funktional sehr gute Softwaresysteme entstanden sind, diese allerdings nicht in jedem Fall optimal betrieben, gewartet und nachgenutzt werden konnten. Zudem wiederholten sich zunehmend ähnliche fachliche Anforderungen nach Suche in Metadaten, Authentifizierung, Erfassung und Verwaltung der Metadaten sowie Präsentation der Metadaten. Diese nicht funktionalen Anforderungen führten zur Suche nach neuen Architekturansätzen für Enterprise Software. Microservices versprechen auf den ersten Blick viele der Anforderungen zu erfüllen, nun sind aber die bekannten Fragen zu klären:

  • Wie definieren sich Microservices?
  • Wann sollte die Microservices Architektur verwendet werden?
  • Wie entwickle ich konkret Microservices?
  • Wie betreibe ich Microservices?
  • Erreiche ich mit Microservices die nicht funktionalen Anforderungen besser?

Alle diese Fragen waren auch nach der Lektüre etlicher Fachaufsätze und Publikationen für uns nicht eindeutig genug zu beantworten. Im Großen und Ganzen liegt es an der Komplexität und Umfang der Gesamtarchitektur der IT Systeme der Staatsbibliothek und dem auch aus Informatikersicht anspruchsvollen Thema Microservices. Es gibt bei der Staatsbibliothek nicht den klassischen Fall eines bestehenden, monolithischen Systems welches mit der Microservice Architektur ersetzt oder ergänzt werden soll. Es gibt auch nicht die *eine* Webpräsentation, auf welche alle Usecases und Fachlichkeiten dargestellt und realisiert werden. Anstelle dessen gibt es sehr viele heterogene Anwendungssysteme auf einer gemeinsamen Infrastruktur.

Um nun genau zu evaluieren, ob und in welchem Umfang Microservices einige Dinge innerhalb der IT Landschaft der Staatsbibliothek verbessern können, und diese wirklich als ganzheitliches Integrationskonzept gesehen werden kann, sollen diese Fragestellungen nun in einem eigenständigen Projekt geklärt werden.

Im Rahmen dieses Projektes werden ich und meine Kollegen dieses Blog regelmäßig mit Informationen zum Thema Microservices und unseren Erfahrungen dazu ergänzen. Unsere Ziele sind:

  • Einen noch höheren Grad der fachlichen Nachnutzung einzelner Services
  • Eine einheitliche Integrationsstrategie
  • Eine Infrastrukturplattform die Microservices bzw. die fachlichen Anwendungen ausfallsicherer, höher verfügbar, skalierbarer und flexibler macht
  • Schnellere Realisierung von fachlichen Anforderungen

Ein guter Einstieg in das Thema Microservices ist dieser Beitrag von Martin Fowler. Hier werden die grundlegenden Fragestellungen erörtert sowie auf viele weitere Informationsquellen verwiesen.

Ebenfalls empfehle ich das Buch zum Thema Microservices mit dem Titel „Microservices: Grundlagen der flexiblen Softwarearchitektur“ von Eberhard Wolff.

Natürlich freuen wir uns auf Kommentare, sollten Sie in Ihren Einrichtungen bereits Erfahrungen mit Konzeption und dem Einsatz von Microservices gesammelt haben.