Beiträge

Microservices, Dokumentenmanagement

In diesem Beitrag unserer Blogserie zum Thema Microservices möchte ich die Vorteile dieses Architekturstiles an einem konkreten Beispiel einer Bibliotheksanwendung aufzeigen. Die hier erläuterten Erfahrungen haben wir in unserem Microservices Projekt im Bereich der Nachweissysteme machen dürfen und möchten diese gerne weiter geben.

Im Laufe unserer Arbeit für die Staatsbibliothek sind durch die Fachabteilungen für unterschiedlichste Anwendungen sehr häufig ähnliche oder gar identische Anforderungen genannt worden. Eine sehr oft formulierte Anforderung war das Management von XML-Dateien. Diese sollten in der Regel abgelegt, verändert, validiert, transformiert oder indiziert werden. Zielstellung dieses Verarbeitungsprozess war in der Regel die Präsentation der im XML enthaltenden Daten im Web.

Die klassische Herangehensweise bereits umgesetzter Projekte war hierbei die Evaluierung und Auswahl eines geeigneten Dokumentenmanagementsystems (DMS) und die Umsetzung der fachlichen Anforderungen innerhalb des DMS. Dabei wurden die im Bibliothekswesen sehr verbreiteten Systeme Mycore, Fedora, DSpace oder aber auch XML Datenbanken verwendet. Diese Systeme bieten in der Regel eine maschinelle Schnittstelle um die XML Dateien zu importieren, exportieren und zu manipulieren. Je nach DMS bietet dieses weitere Funktionen, wie zum Beispiel:

 

  • Generierung eines Indexes zur Suche,
  • Generierung einer Webpräsentation,
  • OAI-Schnittstelle,
  • Aufnahme von Metadaten,
  • Rechtemanagement,
  • Clusterbetrieb,
  • Massenverarbeitung

 

Dabei werden die DMS Funktionalitäten entweder direkt durch eine Webpräsentation oder aber durch eine selbst entwickelte Clientanwendung benutzt. Was aber ist nun problematisch oder beziehungsweise waren die negativen Erfahrungen mit solch einem Aufbau?

DMS Zugriff ohne Fassade

DMS Zugriff ohne Fassade

Ein problematischer Punkt war in der Regel ein Versionswechsel des DMS. Am Beispiel der Weiterentwicklung von der Fedora Version 3 zu der Fedora Version 4 ist die Schnittstelle des Fedora 4 Systems nicht kompatibel mit der des Altsystems. Diese fehlende Abwärtskompatibilität verursacht einen hohen Entwicklungsaufwand, sobald die Clientanwendung oder die Webpräsentation, basierend auf Fedora 3, auf ein Fedora 4 System migriert werden soll. Diese Aufwände sind technisch notwendig, bringen dem Anwender aber keine neue Funktionalität. Diese Tatsache macht die Rechtfertigung des entstehenden Aufwandes sehr schwer. Was wiederum dazu führen kann, dass die Gesamtanwendung nicht zeitnah weiterentwickelt werden kann.

Ein weiterer Punkt ist die Tatsache, dass die gesamte Fachlogik sehr häufig ebenfalls mit den Möglichkeiten der Dokumentenmanagementsysteme oder deren technischen Funktionen umgesetzt worden sind. Dies bedeutet, dass zum Beispiel die Art und Weise des Nachweises, die fachliche Objekte und die Workflows dort implementiert worden sind. Nicht nur bei einer inkompatiblen Migration, sondern auch bei einem Wechsel der DMS-Software müssen die fachlichen Objekte und Workflows neu entwickelt werden. Ebenfalls aufführen möchte ich hier die fehlende Nachnutzbarkeit. Werden durch eine andere Fachabteilung ähnliche Anforderungen in einem anderen Projekt geäußert, können die bereits entwickelten Funktionen nicht noch einmal verwendet werden. Dies basiert in der Regel auf der sehr engen Integration von Clientanwendung oder Webpräsentation und DMS. Auch im Betrieb solcher Systeme haben sich problematische Punkte aufgezeigt. Ein Ausfall des DMS hat direkt einen kompletten bzw. teilweisen Ausfall der Webpräsentation zur Folge. Eine Veränderung der Konfiguration der DMS-Komponente hat ebenfalls direkte Auswirkungen auf die Webpräsentation. Wartungsarbeiten am DMS bedeuten in der Regel einen Ausfall der Webpräsentation.

 

Aber wie kann nun die Microservice-Architektur in den aufgeführten Punkten eine mögliche Lösung darstellen?

 

Um mögliche Inkompatibilitäten zwischen Versionen eines Dokumentenmanagementsystems oder gar einen Wechsel eines Produktes zu ermöglichen, muss die Clientanwendung oder Webpräsentation von der Dokumentenmanagementsoftware entkoppelt werden. Im Bereich der Softwarearchitektur gibt es dafür eine Lösung, die als Fassade bezeichnet wird. Diese wird zwischen der Clientanwendung und dem DMS aufgebaut. Vorteil dieser Fassade ist es, dass diese jegliche Änderungen der DMS Komponente für die Clientanwendung unsichtbar werden lässt. So muss die Clientanwendung nicht mit jeder Änderung des DMS Systems angepasst werden und kann ausschließlich die fachlichen Objekte und Workflows umsetzen.Was aber hat diese Vorgehensweise mit der Microservice-Architektur zu tun? Bis zu diesem Punkt der Erläuterung, nichts. Setzt man nun aber diese Fassade als Microservice um, gewinnt man auf Seiten der Clientanwendung weitere Vorteile.

 

  • Als Microservice kann die Fassade sehr einfach skaliert und somit vielen Anwendungen zur Verfügung gestellt werden.
  • Als Microservice ist ein Zugriff auf das DMS gegen Netzwerklatenzen gesichert. Für die Zugriffe werden Metriken generiert. Diese können bewertet und ins Monitoring eingebunden werden.
  • Als Microservice kann die Fassade unabhängig von den Clientanwendungen weiterentwickelt werden. Während die Fachlichkeit von einem Entwicklerteam entwickelt wird, kann die Integration eines neuen DMS von einem anderen Team gleichzeitig entwickelt werden. So konnten wir im Laufe unseres Projektes drei unterschiedliche Ablagesysteme in der Fassade integrieren, ohne die Clientanwendung anpassen zu müssen.
  • Als Microservice bietet die Fassade eine hohe Nachnutzbarkeit integrierter DMS. Aufgrund der Vereinheitlichung der Schnittstelle können die unterschiedlichsten Clientanwendungen die Ablagesysteme und deren Funktionen nutzen.
  • Als Microservice kann eine Migration bzw. ein Wechsel des DMS ohne Aufwand im Bereich der Clientanwendung durchgeführt werden.
  • Als Microservice können alle Clientanwendungen von der Weiterentwicklung der Fassade profitieren. Wird ein neues DMS integriert, entsteht der Entwicklungsaufwand nur einmal. Dies bedeutet für alle anderen Clientanwendungen eine deutlich kürze Entwicklungszeit.
DMS Zugriff mit Microservice

DMS Zugriff mit Microservice

 

All diese positiven Auswirkungen dieser Architektur haben natürlich auch ihre Herausforderungen. Wir haben die Erfahrung gemacht, dass, sobald das DMS eine REST- Schnittstelle zur Steuerung bietet, der Aufwand der Integration sehr gering ist. Bietet das DMS hingegen keine REST-Schnittstelle so steigt der Integrationsaufwand. Eine weitere  Herausforderung bei dieser Vorgehensweise ist die Schaffung und Weiterentwicklung der einheitlichen Schnittstelle der DMS-Fassade. Diese muss die unterschiedlichen Adressierungen und Steuerungsmöglichkeiten aller DMS zu einem Standard-API zusammenführen. Um alle Möglichkeiten der Microservice-Architektur nutzen zu können, müssen die bereits vorgestellten „Platform Services“ aufgebaut und betrieben werden. Dies vereinfacht zwar den Betrieb, bedeutet initial aber einen Mehraufwand.

 

Fazit

In Anbetracht der aufgezeigten Vorteile fällt mein Feedback zur Microservice-Architektur im Ergebnis positiv aus. Mit sorgfältiger Planung lassen sich die Herausforderungen dieser Architektur meistern. Der initiale Mehraufwand ist meiner Meinung nach mit dem geringeren Aufwand im Dauerbetrieb zu rechtfertigen. Allerdings fehlen zum heutigen Zeitpunkt  noch die Langzeiterfahrung im produktiven Betrieb einer Microservice-Architektur. Aus diesem Grund  würde ich mich sehr über einen Erfahrungsaustausch zum Thema Microservices im Produktionsbetrieb oder ein Feedback zu diesem Beitrag freuen.

Microservices, Integration

Die Microservices Architektur bietet den Vorteil der freien Technologieauswahl bei jedem Microservice. Ein wichtiger Punkt unseres Evaluierungsprojektes war die Prüfung der Integrationsfähigkeit von Softwarekomponenten, welche nicht Java, bzw. Spring Cloud im Technologiestack enthalten. Dazu möchte ich in diesem Beitrag unserer Blogserie zeigen auf welche Art und Weise wir legacy Software, wie zum Beispiel Fedora4 Content Repository in die „Platform Service“ der Microservices Welt integriert haben.

 

Integration

Für die Integration solcher “nicht Java basierten Softwarekomponenten” stellt Netflix Open Source Stack (Netflix OSS) das Projekt Prana bereit. Prana ist eine sogenannte Sidecar Anwendung. Durch die Nutzung von Prana ist es möglich die “Platform Service“, wie zum Beispiel Eureka, Circuit Breaker und Ribbon in solchen Projekten zu verwenden. Wie der Name “Beistellwagen” schon verrät wird das Prana Projekt lediglich neben den nicht Netflix fähigen Microservice gestellt und konfiguriert. Wie genau das funktioniert, möchte ich gerne an folgendem konkreten Beispiel demonstrieren.

 

Dazu haben wir im ersten Schritt ein Spring Boot Projekt aufgesetzt und Spring Cloud Sidecar durch folgende Annotation an der “main” Klasse aktiviert.

 

@EnableSidecar

@SpringBootApplication

public class SideCarApplication {

 

public static void main(String[] args) {

SpringApplication.run(SideCarApplication.class, args);

}

}

 

Anschließend müssen im Sidecar Projekt noch folgende Properties gesetzt werden:

 

spring.application.name=Fedora4-Sidecar

server.display-name=Staatsbibliothek Fedora Sidecar

server.port=9080

sidecar.health-uri=http://localhost:8080/rest/health.json

sidecar.port=8080

sidecar.home-page-uri=http://localhost:8080/

 

Mit der Angabe der health-uri wird auf einen REST Endpunkt der Fedora4 Anwendung verwiesen, aus welchem Sidecar die Statusinformation zur Übermittlung an Eureka erhält. Dazu haben wir im Fedora4 folgendes triviales JSON Dokument hinterlegt:

health.json

{“status”:”UP”}

Bei erreichbarem Fedora4 kann Sidecar nun diese Statusinformation an Eureka übermitteln. Sidecar muss auf demselben Server laufen wie Fedora4. Zusätzlich zur Sidecar Konfiguration müssen natürlich noch die Konfigurationswerte für Eureka, Hystrix und Ribbon gesetzt werden. Um Fedora4 in Eureka sichtbar zu machen haben wir daher für die Service Registry folgende Werte gesetzt:

 

eureka.instance.leaseRenewalIntervalInSeconds=10

eureka.client.healthcheck.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8761/serviceregistry/eureka/

eureka.client.registryFetchIntervalSeconds=5

 

Ist Fedora4 gestartet zeigt Eureka die Integration wie folgt an:

fedora-sidecar

Ist das Sidecar Projekt gestartet und verfügbar, kann anschließend Fedora4 über folgende URL angesteuert werden:

 http://<hostname>:9080/fedora4-sidecar/

 

Welche Vorteile bringt uns diese Integration nun aber ganz konkret.

 

  • ohne Fedora4 anpassen zu müssen, lässt es sich in die “Platform Services” von Netflix integrieren,
  • Fedora4 ist damit in der Service Registry sichtbar und abrufbar,
  • ein Aufruf von Fedora4 über die Sidecar URL wird als Circuit Breaker Command ausgeführt,
  • es werden Hystrix Metriken generiert welche im Hystrix Dashboard sichtbar sind,
  • es kann Load Balancing verwendet werden, sobald Fedora4 mehrfach installiert ist,
  • es kann die zentrale Configuration Management Instanz verwendet werden.

 

Obwohl Fedora4 kein Microservice ist können Client Anwendungen die Service Registry nach der Einstiegs URL von Fedora4 fragen. Anschließend wird jede Anfrage der Clients via Hystrix abgesichert und aufgezeichnet. So konnten wir zum Beispiel die Antwortzeiten der Fedora4 REST API im Hystrix Dashboard aufzeichnen und auswerten.

hystrix-fedora

All diese Vorteile sind ohne eine einzige Anpassung des Fedora4 Systems möglich. Auf dieselbe Art  und Weise haben wir einen reinen Javascript Microservice eingebunden.

 

Fazit

Wie dieser Beitrag zeigt, ist die Integration einer Softwarekomponente, welche nicht den Netflix Stack via Bibliotheken Integration nutzen kann, sehr einfach. Die aufgezeigten Möglichkeiten, welche sich dadurch bieten finde ich beeindruckend. Hinzufügen muss ich allerdings, dass sich auf diese Art und Weise nur Softwarekomponenten integrieren lassen, welche über eine REST API angesprochen werden können. Da alle Aufrufe dieser REST API über Sidecar geroutet werden. Für Softwarekomponenten ohne REST API ist die Integration ebenfalls möglich aber etwas aufwendiger.

Microservices, Widerstandsfähigkeit

Widerstandfähigkeit eines Microservices Systems in Bezug auf Serviceausfälle oder Netzwerklatenz war ein wichtiger Aspekt, welchen wir in unserem Microservices Projekt eingehend untersuchen wollten. Daher freue ich mich dieses Thema und unsere Erfahrungen in unserer Blogserie etwas eingehender beleuchten zu können.

Widerstandsfähig bezieht sich hierbei auf die Client Anwendung, welche die einzelnen nachgelagerten Microservices verwendet. Dieser Begriff meint dabei, dass die Client Anwendung auch im Fall von Netzwerk- bzw. Serviceausfällen nicht blockiert und immer noch durch den Anwender verwendet werden kann. Blockieren kann die Anwendung zum Beispiel, wenn diese einen Microservice verwendet, welcher sehr viel Zeit benötigt, um eine Antwort im Netzwerk bereit zu stellen. Warum dieser Microservice nicht schnell genug antwortet, spielt bei dieser Betrachtung keine Rolle. Die Client Anwendung wartet solange bis entweder die Antwort eintrifft oder aber ein zuvor definierter Timeout einen Fehler erzeugt. Eine hohe Wartezeit einer Anfrage kann bei starker Verwendung der Client Anwendung dazu führen, dass immer mehr Anfragen der Nutzer das System immer stärker blockieren. Ein Blockieren der Client Anwendung kann aber auch durch eine Überlastung des Netzwerks ausgelöst werden. Die Client Anwendung fühlt sich in solchen Fällen für den Nutzer träge und langsam an. Im Falle von Webanwendungen verlässt der Nutzer in der Regel dann sehr schnell die Seite.

 

Als Lösung für solche Situationen bietet der Netflix OSS das Projekt Hystrix, als sogenannte „Circuit Breaker“ Bibliothek, an. Ein „Circuit Breaker“ ist eine Sicherung, welche ausgelöst wird, sobald gewisse Umstände eintreten. Hystrix bietet darüber hinaus viele zusätzliche Funktionalitäten:

 

  • kapselt ein Kommando und bietet synchrone und asynchrone Ausführung,
  • löst nach definiertem Timeout die Sicherung aus,
  • führt jedes Kommando in einem definierten Thread Pool aus,
  • auslösen der Sicherung bei zu hoher Fehlerrate eines Kommandos,
  • ermöglicht die Ausführung eines Fallbacks im Fehlerfall,
  • erzeugt Performance Metriken,
  • ermöglicht die Nutzung eines Caches.

 

Alle diese Funktionalitäten stehen zur Verfügung, sobald ein in der Client Anwendung ausgeführtes Kommando in ein “HystrixCommand” überführt wird. Meiner Meinung nach ist es wichtig, den nachfolgend abgebildeten Ablauf der Ausführung eines Hystrix Kommandos zu verstehen.

Abbildung .1: Netflix, Hystrix Command Fflow Chart, Web URL: https://github.com/Netflix/Hystrix/wiki/How-it-Works [Stand 2016-05-25]

Abbildung .1: Netflix, Hystrix Command Flow Chart, Web URL: https://github.com/Netflix/Hystrix/wiki/How-it-Works [Stand 2016-05-25]

Die detaillierte Beschreibung des Ablaufs finden Sie hier. Der Grund, warum ich diese Abbildung hier aufgeführt habe ist, dass diese sehr schön zeigt, dass Hystrix nicht nur ein reiner Ciruit Breaker ist. Wie zu erkennen ist, bietet Hystrix ein definiertes Verfahren zur Absicherung eines Netzwerkkommandos. Es besteht mit Hilfe der Hystrix Metriken die Möglichkeit sehr einfach und bequem Antwortzeiten auszuwerten. Durch die Integration konnten wir in unserem Projekt die Antwortzeiten eines Fedora4 Content Repository Servers, eines EMC S3 Object Storage Servers und des lokalen Dateisystems vergleichen. Die Hystrix Metriken konnten wir sehr einfach mittels des Hystrix Dashboards visualisieren und in Echtzeit auswerten. So kann auch in produktiven Umgebungen die Reaktions- bzw. Widerstandsfähigkeit einzelner Systeme optimal bewertet werden. Dies ersetzt natürlich keine umfassende Monitoringlösung, bietet aber die Möglichkeit, die Auslastung einzelner Systeme schnell zu erkennen und richtig zu behandeln.

 

Die Integration

Die Integration von Hystrix ist, wie auch bei den anderen “Platform Services” Komponenten, einmal mittels der nativen Netflix Bibliothek oder aber auch über das Spring Cloud Projekt möglich. In unserem Projekt haben wir beide Möglichkeiten erfolgreich durchgeführt.Spring Cloud bietet eine sehr einfache und leichte Integration via Annotation:

 

Beispiel:

@HystrixCommand(commandKey = “DMS->EMCS3:findObjectContent”, groupKey = “DMS->EMCS3”)

 

Hierbei wird lediglich der Name des Kommandos und des Threadpools definiert. Es ist über die Zusatzbibliothek hystrix-javanica zusätzlich möglich, alle Konfigurationswerte direkt in der Annotation aufzuführen. Wir haben uns allerdings dazu entschieden, die Konfiguration in der zentralen „application.properties“ Datei durchzuführen.

 

Im Bereich der nativen Netflix Bibliothek ist die Integration ebenfalls sehr leicht. Nach dem Einbinden der Abhängigkeiten hystrix-core und hystrix-metrics-event-stream kann die Integration durchgeführt werden. Die Klasse, mit welcher ein Kommando im Netzwerk ausgeführt wird, muss lediglich die Klasse HystrixCommand erweitern und die Methode run() implementieren. Die Konfiguration erfolgt über die Datei “eureka-client.properties”.

Bei einigen Standardwerten der Konfiguration mussten wir Anpassungen vornehmen, da Hystrix die Sicherung für unseren Anwendungsfall zu schnell ausgelöst hat. Dies ist uns bei Belastungstests mit dem Werkzeug JMeter aufgefallen. Letztendlich konnten wir mit folgenden Einstellungen ein sehr gutes Antwortverhalten bei einer stark belasteten Komponente erzeugen:

 

hystrix.command.default.execution.isolation.strategy=THREAD

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=120000

hystrix.command.default.execution.isolation.thread.maxConcurrentRequests=1024

hystrix.command.default.fallback.isolation.thread.maxConcurrentRequests=1024

hystrix.threadpool.default.coreSize=1024

hystrix.threadpool.default.maxQueueSize=1024

hystrix.threadpool.default.keepAliveTimeMinutes=2

hystrix.threadpool.default.queueSizeRejectionThreshold=15

hystrix.threadpool.default.metrics.rollingStats.numBuckets=12

hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds=1440  

 

Sich diese Konfigurationswerte genau zu betrachten und diese festzulegen, ist ein wichtiger Schritt bei der Integration von Hystrix. Allerdings muss natürlich jeder selbst entscheiden, welche Werte für welches Kommando sinnvoll sind.

 

Fazit

Die Integration ist, wie bereits bei den anderen “Platform Services” des Netflix OSS, nicht sehr aufwendig. Dieses Werkzeug, finde ich persönlich, wegen der vielen zusätzlichen Funktionalitäten sehr interessant und nützlich. Es bietet eine standardisierte Lösung, um ein Netzwerkkommando gesichert auszuführen, ein Fallback zur Verfügung zu stellen, einen Cache zu nutzen und Performancemesswerte zu erzeugen. In Zukunft werde ich für mich persönlich daher immer bewerten, ob nicht die Verwendung dieser Bibliothek bei jeglichen Netzwerkzugriffen eines Projektes sinnvoll ist.