Entwurf und Umsetzung einer nachrichtenorientierten Software-Architektur am Beispiel eines SmartCampus-Dienstes


Masterarbeit, 2016
97 Seiten, Note: 1,3

Leseprobe

Inhaltsverzeichnis

1 Einleitung

1 Einleitung
1.1 Einführung in das Themengebiet
1.2 Fragestellungen
1.3 Beschreibung des Demonstrators
1.3.1 Funktionale Anforderungen aus Sicht der Studierenden
1.3.2 Funktionale Anforderungen aus Sicht der Sachbearbeiter
1.4 Gliederung der Arbeit

2 Grundlagen
2.1 Das Reaktive Manifest
2.2 Ereignisgesteuerte Architektur
2.2.1 Grundkonzepte
2.2.2 Schichten
2.2.3 Vorteile
2.2.4 Nachteile
2.3 Nachrichtenorientierte Architektur
2.3.1 Hauptelemente
2.3.2 Kommunikationsmodelle
2.3.3 Vorteile
2.3.4 Nachteile
2.4 Microservices
2.4.1 Definition
2.4.2 Grundlegende Eigenschaften
2.4.3 Deployment-Strategien
2.4.4 Vorteile
2.4.5 Nachteile
2.5 REpresentational State Transfer (REST)
2.5.1 Architektur
2.5.2 Methoden
2.6 Web Components
2.7 Angular
2.7.1 TypeScript
2.7.2 Grundkonzepte
2.7.3 Vergleich zu anderen Web Frameworks
2.8 Web Workers
2.8.1 Definition
2.8.2 Klassen

3 Stand der Technik
3.1 A Message-based Software Architecture Style for Distributed Application
3.1.1 Grundkonzepte
3.1.2 Bewertung
3.2 Hierarchical message bus-based (HMB) software architecture style
3.2.1 HMB-Architekturelemente
3.2.2 Bewertung
3.3 Message-Oriented-Middleware in a Distributed Environment
3.3.1 Grundkonzepte
3.3.2 Bewertung
3.4 Nachrichtenbasierte Web-Präsentation für das serviceorientierte SmartCampus-System (SC-NBWP)
3.5 Vergleich

4 Konzept für eine nachrichtenorientierte Software-Architektur für web-basierte Software-Systeme
4.1 Grundkonzepte
4.2 Hauptelemente
4.3 Kommunikationsmechanismen
4.3.1 Push- und topic-basierte Kommunikation
4.3.2 Punkt-zu-Punkt-Kommunikation und Publish/Subscribe
4.3.3 Nachrichtenprotokolle
4.3.4 RPC Messaging

5 Konzept für die Umsetzung des Demonstrators
5.1 Message Bus
5.1.1 Grundkonzepte von RabbitMQ
5.1.2 Anwendung der RabbitMQ-Konzepte bei der Umsetzung des Demonstrators
5.2 Client Components
5.2.1 Eingesetzte Technologien und Konzepte
5.2.2 Touchscreen-Web-Anwendung
5.2.3 Web-Anwendung für die Anzeigebildschirme vor Ort
5.2.4 Windows-Druck-Service
5.2.5 Windows-Client-Anwendung zum Ziehen einer Wartemarke durch Scannen der KIT-Karte
5.2.6 SmartCampus-Ticket-Service-Gruppe
5.3 Server Components
5.3.1 Eingesetzte Technologien
5.3.2 StudAdviceTicket Microservice
5.3.3 Notification Microservice
5.3.4 StudentCard Microservice
5.4 Datenimporter

6 Zusammenfassung und Ausblick
6.1 Zusammenfassung
6.2 Ausblick

Anhänge
A Abkürzungen und Glossar
B Abbildungen
C Literaturanalysen
D Literatur

1 Einleitung

Das Einleitungskapitel beginnt mit einer kurzen Einführung in das in der vorliegenden Masterarbeit betrachtete Themengebiet auf hoher Abstraktionsebene. Anschließend werden Fragestellungen, Qualitätsaspekte und nichtfunktionale Anforderungen diskutiert, aus denen sich die Notwendigkeit der Arbeit ergibt. Zum Schluss dieses Kapitels erfolgt die Beschreibung eines Demonstrators samt funktionalen Anforderungen, anhand dessen die bereits vorgestellten Fragestellungen verdeutlicht und praktisch gelöst werden.

1.1 Einführung in das Themengebiet

Moderne Web-Anwendungen stellen heutzutage große Herausforderungen an die Software-Entwicklung. Sie müssen einerseits bestimmte funktionale Anforderungen erfüllen, die für die Kundenzufriedenheit eine wesentliche Rolle spielen, andererseits sind Qualitätsaspekte und nichtfunktionale Anforderungen während des Entwicklungsprozesses zu berücksichtigen, die langfristig für die Qualität des Software-Produkts ausschlaggebend sind.

Bislang wurden Benutzerschnittstellen meist von Grund auf neu entwickelt und miteinander und anderen Teilen des Gesamtsystems stark gekoppelt, was Änderungen und die Weiterentwicklung erschwert und oft unmöglich macht. Der Einsatz heterogener Frameworks und Technologien erleichtert zwar die Entwicklung, da sie viele Grundfunktionalitäten anbieten und als Grundlage dienen, führt aber zu technologischen Abhängigkeiten.

Ein weiteres Problem bei der heutigen Generation von Web-Anwendungen ist die synchrone Request/Response-Kommunikation zwischen zwei Endpunkten (meistens Client und Server). Bei diesem Kommunikationsmodell schickt ein Client eine Anfrage an einen Server, der nach ihrer Verarbeitung sich mit einer Antwort zurückmeldet. Eine Einschränkung dieses weit verbreiteten Modells ist, dass die Kommunikation nur zwischen den beiden Endpunkten stattfinden kann und keine Multicast-Kommunikation (von einem Endpunkt zu einer Gruppe) möglich ist. Diese Einschränkung kann durch Versenden mehrerer Anfragen nacheinander umgegangen werden, was extrem aufwendig ist. Ein weiteres Problem bei diesem Mechanismus ist, dass die Kommunikation zwischen Client und Server nur dann stattfindet, wenn der Client eine Anfrage an den Server gestellt hat, d.h. ohne eine explizite Anfrage sendet der Server keine Daten in Richtung Client. Es besteht auch keine Möglichkeit zu einem gleichzeitigen Datenaustausch in beiden Richtungen.

Die heutigen modernen Web-Anwendungen und ihre Bestandteile müssen all diese Herausforderungen überwinden und Eigenschaften wie Wiederverwendbarkeit, Anpassbarkeit, Übertragbarkeit durch geringe Plattformabhängigkeit, Wartbarkeit, modulare Testbarkeit, kontinuierliche Verfügbarkeit, Zuverlässigkeit, Skalierbarkeit, Robustheit und Gebrauchstauglichkeit (Usability) aufweisen. Nur dann entstehen qualitativ hochwertige Software-Produkte, die anpassbar und flexibel bei Änderungen sind und auch leicht weiter entwickelt werden können.

1.2 Fragestellungen

Die Berücksichtigung der bereits vorgestellten Herausforderungen, Probleme und Qualitätsaspekte bei den heutigen Web-Anwendungen erfordert angepasste Architekturkonzepte. Daraus ergeben sich viele Fragen, die im Rahmen dieser Masterarbeit konzeptionell und praktisch beantwortet und im Folgenden eingeführt werden.

1. Wie sieht ein Konzept für eine Architektur einer Web-Anwendung aus, die auf Anpassbarkeit, Wartbarkeit und Nachhaltigkeit fokussiert?

Der Fokus von Service-orientierten Architekturen (SOA) liegt auf genau diesen drei wichtigen nichtfunktionalen Anforderungen an eine Software. Bei diesem Architekturmodell werden separate, über das Internet verteilte Dienste, die diverse Fähigkeiten anbieten und einheitlich zur Verfügung gestellt werden, in neue Systeme eingebunden.

2. Wie kann das Problem mit der engen Kopplung zwischen den Bestandteilen einer Web-Anwendung sinnvoll gelöst werden?

Die Microservices-Architektur bietet gute Möglichkeiten zu einer losen Kopplung oder Entkopplung der Elemente einer Web-Anwendung. Bei diesem Architekturmodell existieren mehrere kleine, vollkommen unabhängige und getrennt deploybare funktionale Einheiten (Microservices), die in eine Grundarchitektur eingebettet werden.

Ein weiteres relevantes Konzept sind die sogenannten Web Components. Diese ermöglichen eine lose Kopplung, Modularität und Wiederverwendung von Komponenten auf der Repräsentationsebene.

3. Was ist der beste Mechanismus zur Kommunikation zwischen den Komponenten einer modernen Web-Anwendung?

Verteilte Kommunikation über Ereignisse und Nachrichten garantiert Flexibilität und Anpassbarkeit. Deswegen ist eine ereignisgesteuerte Architektur mit nachrichtenorientierter Kommunikation ein erfolgversprechendes Modell. Dabei lösen Ereignisse in Komponenten eine bestimmte Nachricht aus und informieren alle Komponenten, die das jeweilige Ereignis abonniert haben. Die abonnierten Komponenten bekommen eine Nachricht zum entsprechenden Ereignis. Die Kommunikation erfolgt mit Hilfe von Nachrichten nach dem Publish/Subscribe-Prinzip. Dieser Ansatz löst somit das bereits beschriebene Problem mit der synchronen Request/Response-Kommunikation.

1.3 Beschreibung des Demonstrators

Der Demonstrator soll eine praktische Umsetzung der auf konzeptioneller Ebene gelösten Fragestellungen aufzeigen. Er soll ein fertiges Software-Produkt sein, das produktiv eingesetzt werden kann.

Im Rahmen dieser Arbeit soll ein web-basiertes Аufrufsystem, das zur Verwaltung von Warteschlangen bei Kundendiensten dient, entstehen. Dieses Software-System soll zum Aufruf von Studierenden in Warteschalge beim Studierendenservice am Karlsruher Institut für Technologie (KIT) zur Anwendung gebracht werden. Die derzeit vom KIT-Studierendenservice eingesetzte kommerzielle Software ist technologisch veraltet und es besteht keine Möglichkeit zur Anpassung, Weiterentwicklung und Unterstützung mobiler Geräte. Außerdem ist es kein web-basiertes System, sondern eine Client-Software, die einen aufwändigen Wartungsprozess erfordert. Das gesamte Aufrufsystem soll das bestehende ersetzen und aus den folgenden Modulen oder Teilsystemen bestehen:

1. web-basiertes Aufrufsystem als Teil der SmartCampus-Plattform, durch das ein Student eine Wartemarke online ziehen kann und ein Sachbearbeiter Wartende aufrufen kann
2. web-basiertes System, das die aktuelle Wartesituation auf Anzeigebildschirmen vor Ort im Studierendenservice anzeigt
3. web-basiertes System, das es ermöglicht, eine Wartemarke durch Auswahl von Studiengang oder eine allgemeine Kategorie und bei Bedarf Buchstabenbereich des Nachnamens vor Ort im Studierendenservice zu ziehen
4. Windows Client, das es ermöglicht, eine Wartemarke durch Scannen der KIT-Karte vor Ort im Studierendenservice zu ziehen

Daraus ergeben sich folgende funktionale Anforderungen an das System, die auf Abbildung 1 und Abbildung 2 dargestellt sind und im Folgenden vorgestellt werden.

1.3.1 Funktionale Anforderungen aus Sicht der Studierenden

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 1: Anwendungsfalldiagramm zur Funktionalität des Aufrufsystems aus Sicht der Studierenden

Ein Student kann mit dem web-basierten SmartCampus-Aufrufsystem nur dann arbeiten nachdem er sich mit seinem KIT-Account angemeldet hat. Ohne vorherige Anmeldung kann eine Wartemarke nur über den Touchscreen oder durch Scannen der KIT-Karte vor Ort gezogen werden. Eine Verfolgung der Wartesituation und der aktuellen Aufrufe ist im Anwendungsfall ohne Anmeldung auch nur über die Bildschirme vor Ort möglich.

Wenn ein Studierender eine Wartemarke online zieht, kann er eine kurze Beschreibung seines Anliegens hinzufügen, sowie die Kategorie dieses Anliegens festlegen, indem er sie aus einer vorgegebenen Liste auswählt oder selber eingibt.

Ihm werden auch die aktuellen Aufrufe und die Wartesituation für seinen Wartekreis in Echtzeit angezeigt und seine Position in der Warteschlange wird vom System markiert. Die Wartesituation wird automatisch aktualisiert. Durch Aktivieren der entsprechenden Funktion kann der Studierende auch eine Benachrichtigung auf seinem Endgerät bekommen, wenn er sich an einer von ihm festgelegten Position in der Warteschlange befindet oder seine voraussichtliche Wartezeit einen bestimmten Wert beträgt. Die Benachrichtigungsoption kann jederzeit von ihm deaktiviert werden. Bei Stornieren einer Wartemarke kann die Aufrufnummer nicht mehr aufgerufen werden und die Wartesituation wird automatisch aktualisiert. Stornieren ist nur über die SmartCampus-Web-Anwendung nach vorheriger Anmeldung möglich.

1.3.2 Funktionale Anforderungen aus Sicht der Sachbearbeiter

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 2: Anwendungsfalldiagramm zur Funktionalität des Aufrufsystems aus Sicht der Sachbearbeiter

Ein Sachbearbeiter kann nur nach vorheriger Anmeldung mit dem System arbeiten. Er kann den nächsten Wartenden aufrufen. Falls ein Student über die web-basierte SmartCampus-Software oder durch Scannen der KIT-Karte eine Wartemarke gezogen hat, bekommt der Sachbearbeiter beim Aufruf des Wartenden seine Daten direkt vom Campus-Management-System auf seinem Bildschirm. Nach Bearbeitung des Anliegens kann der Sachbearbeiter eine kurze Beschreibung der Lösung des Problems oder Anliegens verfassen und speichern, die in Zukunft bei ähnlichen Problemen oder Anliegen nützlich sein kann. Die Software bietet auch die Möglichkeit, nach ähnlichen Problemen oder Anliegen und ihren Lösung in der Datenbank zu suchen. Dabei kann vorher die Problemkategorie ausgewählt werden. Jeder Sachbearbeiter bearbeitet in der Regel bestimmte Wartekreise. Ihm ist ein Wartekreis vom System standardmäßig zugeordnet. Er kann seine Wartekreise aber auch selber auswählen und beispielsweise seinen Wartekreisen neue Wartekreise hinzufügen, wenn es zu wenig Wartende aus den Wartekreisen, die er aktuell bearbeitet, gibt. Es existieren folgende Wartekreise: G-XX, W-XX, RA-XX, RB-XX, YA-XX, YB-XX, BA-XX, BB-XX. In jedem Wartekreis befinden sich Studierende aus bestimmten Studiengängen und Buchstabenbereichen des Nachnamens. Die Aufrufnummern bestehen aus einem oder zwei Buchstaben, die den Wartekreis identifizieren und auch aus zwei Ziffern. Die Ziffern beginnen jeden Tag mit 00 und werden mit jeder Wartemarke getrennt nach Wartekreis um eins erhöht. Beispiele für Aufrufnummern sind: G-00, G-01, RA-00, RA-45, BB-45.

1.4 Gliederung der Arbeit

Die vorliegende Masterarbeit ist folgendermaßen aufgebaut:

Kapitel 2: Grundlagen

In diesem Kapitel erfolgt eine Einführung in die grundlegenden Konzepte, Architekturen, Begriffe und Frameworks, die eine Grundlage für die in den nachfolgenden Kapiteln betrachteten Ansätze bilden. Das Kapitel beginnt mit einer kurzen Vorstellung des Reaktiven Manifests [BF+14], das vier Anforderungen an ein modernes Software-System definiert. Alle Konzepte, die in diesem Kapitel dargelegt werden, liefern einen Beitrag zur Erfüllung dieser Anforderungen.

Anschließend werden die Grundkonzepte von ereignisgesteuerten und nachrichtenorientierten Architekturen präsentiert. In den nächsten zwei Unterkapiteln werden Microservices samt ihren grundlegenden Eigenschaften definiert und REpresentational State Transfer (REST) als Architekturparadigma erläutert. Danach erfolgt eine Spezifikation von Web Components, gefolgt von einer kurzen Vorstellung eines konkreten Frameworks zur Entwicklung von wiederverwendbaren Web Components – Angular 2. Zum Schluss wird das Konzept der Web Workers vorgestellt, die zu einer wesentlichen Verbesserung der Performanz einer Web-Anwendung beitragen und Elastizität gewährleisten.

Kapitel 3: Stand der Technik

In diesem Kapitel werden bestehende Konzepte und Ansätze für den Aufbau einer nachrichtenorientierten Software-Architektur vorgestellt, analysiert, bewertet und verglichen. Am Anfang wird der Tree-Software-Architecture -Ansatz [TL+05] samt seinen Grundkonzepten kurz vorgestellt und anschließend bewertet. Im nächsten Unterkapitel erfolgt eine Beschreibung der Grundprinzipien und der Architekturelemente von Hierarchical message bus-based software architecture style [SL+02], gefolgt von einer kritischen Bewertung seiner Konzepte. Der dritte analysierte Ansatz ist Message-Oriented-Middleware in a Distributed Environment [GS+03]. Im vierten Unterkapitel erfolgen eine kurze Zusammenfassung des im Rahmen der Bachelorarbeit von Florian Dreschner [Dr16] entwickelten Konzepts, sowie eine Analyse seiner Vorteile und Schwachstellen. Zum Schluss werden alle Ansätze nach vorher definierten Kriterien miteinander verglichen.

Kapitel 4: Konzept für eine nachrichtenorientierte Software-Architektur für web-basierte Software-Systeme

In Kapitel 4 wird das im Rahmen dieser Masterarbeit entwickelte Architekturkonzept detailliert vorgestellt. Im ersten Unterkapitel erfolgt ein Überblick über die Grundkonzepte der Architektur. Im nächsten Unterkapitel werden die Hauptelemente der nachrichtenorientierten Software-Architektur präsentiert und anschließend die Kommunikationsmechanismen ausführlich erläutert.

Kapitel 5: Konzept für die Umsetzung des Demonstrators

In diesem Kapitel erfolgt eine ausführliche Vorstellung eines Konzepts für die Umsetzung eines Aufrufsystems zur Verwaltung von Warteschlangen, das als Demonstrator dient. Dieses Konzept basiert auf dem in Kapitel 4 vorgestellten Konzept für eine nachrichtenorientierte ereignisgesteuerte Software-Architektur. Im ersten Unterkapitel wird eine konkrete Lösung für die Message-Bus-Komponente vorgestellt. Im nächsten Unterkapitel wird die Implementierung aller Client Components des Aufrufsystems samt eingesetzten Technologien und technischen Aspekten diskutiert. Im dritten Unterkapitel wird das Konzept für die Umsetzung aller Server Components detailliert erläutert. Das letzte Unterkapitel ist dem Datenimporter – ein Werkzeug, das vom Administrator zur Verwaltung und Konfiguration des Aufrufsystems benutzt werden soll, gewidmet.

Kapitel 6: Zusammenfassung und Ausblick

In diesem Kapitel wird die geleistete Arbeit zusammengefasst und die wichtigsten Konzepte werden in kurzer Form wiederholt. Anschließend werden nichtgelöste Problemstellungen diskutiert und es wird ein Ausblick auf weiterführende Arbeiten gegeben.

2 Grundlagen

Das Grundlagenkapitel führt in die theoretischen Grundlagen ein, die als Fundament für die Konzepte, die später im Rahmen dieser Masterarbeit entwickelt werden, dienen.

2.1 Das Reaktive Manifest

Die Anforderungen bezüglich Performanz, Antwortzeit und Flexibilität an die heutigen modernen Software-Systeme sind sehr hoch und steigen kontinuierlich an. Das Reaktive Manifest [BF+14] ist diesem Thema gewidmet. In diesem kurzen Schriftstück wird der Begriff „reaktives System“ eingeführt und durch vier Anforderungen definiert. Ein reaktives System muss immer antwortbereit, widerstandsfähig, elastisch und nachrichtenorientiert sein [BF+14]. Systeme, die diese Eigenschaften aufweisen, sind stets anpassungsfähig, skalierbar, robust und leicht weiterzuentwickeln. Überdies erzielen solche Software-Systeme eine ideale Benutzererfahrung.

Im Folgenden werden die vier Anforderungen des Reaktiven Manifests näher betrachtet.

Antwortbereitschaft

Jedes reaktive Software-System soll in der Lage sein, dem Benutzer schnell und ohne lange Wartezeiten eine Antwort zu liefern, sodass er das Gefühl einer direkten Interaktion bekommt. In diesem Fall ist es sehr wichtig, bestimmte anwendungsspezifische Antwortzeitgrenzen zu definieren, durch die das Erkennen von Fehlern ermöglicht wird. Wenn keine Antwort innerhalb der vorgegebenen Zeitgrenzen vorliegt, kann von einem Fehlerfall ausgegangen werden. Konsistente Antwortzeiten garantieren gute Qualität und sorgen für eine optimale Benutzererfahrung. [BF+14]

Eine weitere Facette ist, dass bei einem reaktiven System der Benutzer immer im Vordergrund steht. Er muss jederzeit wissen, welche Prozesse das System zum aktuellen Zeitpunkt durchführt und entsprechend durch Rückmeldungen ohne Wartezeiten informiert werden. Ein sehr kritischer Punkt des Lebenszyklus einer Software ist die Zeit, in der diese gestartet wird. Reaktive Systeme sollen die Zeitspanne vom Aufruf bis zur tatsächlichen Darstellung der Applikation möglichst kurz halten. [MIT-SRP]

Widerstandsfähigkeit

Ein System ist widerstandsfähig, wenn es auch bei diversen Ausfällen antwortbereit bleibt. Dies können Software- oder Hardware-Ausfälle sein, aber auch Probleme mit der Verbindung zwischen Client und Server. Anwendungen, die diese Anforderung nicht erfüllen, erweisen sich im Fall von Ausfällen als nicht antwortbereit und sind nicht mehr in der Lage, ihre Funktionen zu erfüllen. Widerstandsfähigkeit kann ausschließlich durch Replikation von Funktionalitäten, lose Kopplung oder Entkopplung von Komponenten, sowie Delegation von Funktionen gewährleistet werden. [BF+14]

Ein Software-System soll somit so aufgebaut werden, dass bei Ausfall einer Komponente andere Komponenten und Teilsysteme davon nicht betroffen sind. Die Funktionen der ausgefallenen Komponente werden dann an ein Replikat dieser Komponente oder an eine übergeordnete Komponente delegiert. Dieser Prozess soll für den Endbenutzer transparent bleiben.

Elastizität

Ein System besitzt diese Eigenschaft, wenn es antwortbereit bleibt, unabhängig davon, unter welcher Last es zum derzeitigen Zeitpunkt steht. Die Grundidee besteht in einer automatischen Anpassung der vom Software-System genutzten Ressourcen, sowie der Replizierungsfaktoren bei Erhöhung bzw. Erniedrigung der Last. Eine Voraussetzung dafür ist, dass das System keine Engpässe aufweist, die das Erreichen der geplanten Maximalleistung verhindern können. Wenn diese Voraussetzung erfüllt ist, können die vom System abzuarbeitenden Aufgaben in Teile zerlegt und auf unterschiedliche Ressourcen verteilt werden. Dies nennt man Lastverteilung. Alle reaktiven Systeme müssen in der Lage sein, den Grad der Auslastung automatisch zur Laufzeit zu ermitteln, um eine automatische Regulierung der genutzten Kapazitäten zu ermöglichen. [BF+14]

Nachrichtenorientierung

Die Architektur jedes reaktiven Systems soll nachrichtenorientiert sein. Durch eine asynchrone Kommunikation über Nachrichten zwischen den Komponenten wird eine lose Kopplung sichergestellt und die Übermittlung von Fehlermeldungen an übergeordnete Komponenten im Fall von Ausfällen ermöglicht. Überdies ist ein Einblick in das Laufzeitverhalten des Systems anhand Überwachung der Nachrichtenflüsse in Nachrichtenpuffern möglich. Dies erlaubt eine automatische Verwaltung der genutzten Ressourcen und Kapazitäten und dient zur Diagnose, sowie Priorisierung und Steuerung der Nachrichtenflüsse. [BF+14]

Systeme, die nachrichtenorientiert sind, weisen ein nicht blockierendes Verhalten auf, was eine der wichtigsten Anforderungen an die heutigen modernen Software-Produkte ist. Das Konzept der nachrichtenorientierten Architekturen wird in einem der nächsten Kapitel ausführlicher betrachtet.

2.2 Ereignisgesteuerte Architektur

Das Konzept der ereignisgesteuerten Architekturen leistet zweifellos einen Beitrag zur Erfüllung der Anforderungen des Reaktiven Manifests, da sie den Grad der Entkopplung der Software-Komponenten, sowie die Anpassungs- und Reaktionsfähigkeit einer Software erhöhen [SS07]. In den nachfolgenden Ausführungen werden die Grundkonzepte einer ereignisgesteuerten Architektur eingeführt, ihre Schichten vorgestellt, sowie Vor- und Nachteile diskutiert.

2.2.1 Grundkonzepte

Im Fokus einer ereignisgesteuerten Architektur stehen Ereignisse. Diese beschrieben eine erkennbare Zustandsänderung eines realen oder virtuellen Objekts und lassen sich technisch mit Hilfe von Nachrichten ausdrücken. Ereignisse können verschiedene Aktivitäten, Vorgänge oder Sachverhalte auf unterschiedlichen Abstraktionsebenen repräsentieren. Beispiele dafür sind technische Ereignisse, System- und Geschäftsereignisse, die bestimmte physikalische Änderungen oder Benutzereingaben signalisieren können. [SS07]

Ein System wird als ereignisgesteuert bezeichnet, wenn das Eintreffen eines oder mehrerer Ereignisse den Verarbeitungsprozess in diesem System anstößt. Die Grundlage eines ereignisgesteuerten Systems bilden die folgenden drei Schritte: Erkennen, Verarbeiten und Reagieren. [BD10a]

Erkennen

Im ersten Schritt müssen relevante Informationen und Aktivitäten erkannt und als Ereignisse registriert werden. Anschließend erfolgt eine Zuordnung von den bereits erkannten Ereignissen zu Ereignisobjekten im System. Bei ereignisgesteuerten Systemen ist es essentiell wichtig, dass die Ereignisse umgehend zum Zeitpunkt, zu dem sie auftreten, als solche erkannt und registriert werden. Andernfalls können Zeitverzögerungen in einem anwendungsspezifischen Kontext fatale Folgen haben. [BD10a]

Verarbeiten

Nachdem die Ereignisse, die auch unterschiedliche Auslöser haben können, als solche erkannt worden sind, findet im nächsten Schritt eine Verarbeitung dieser Ereignisse statt. Dabei werden sie analysiert und aggregiert, klassifiziert und in bestimmten Fällen auch verworfen. Bei dieser Analyse wird auch nach Mustern in den Ereignisflüssen gesucht, um gewisse Zusammenhänge zwischen den Ereignissen zu finden. [BD10a]

Reagieren

Nach der Analyse findet der letzte Schritt - die Reaktion statt. Hier muss aufgrund der im Verarbeitungsschritt erkannten Muster oder Ereignisarten zeitnah auf die Ereignisse entsprechend reagiert werden. Die Reaktionen sind immer anwendungsspezifisch und können zum Beispiel aus dem Verschicken von Meldungen oder der Initiierung neuer Ereignisse auf einer höheren Abstraktionsebene bestehen. [BD10a]

Demensprechend kann der Begriff ereignisgesteuerte Architektur als ein Architekturparadigma bezeichnet werden, bei dem alle Komponenten ereignisgesteuert sind und durch den Austausch von Ereignissen, die mittels Nachrichten ausgedrückt werden, interagieren. Die Verarbeitung von Ereignissen bildet somit das zentrale Konzept bei der Modellierung von Software-Systemen mit einer ereignisgesteuerten Architektur. Ereignisgesteuerte Architekturen können grundsätzlich mit Hilfe von zwei Modellen – Verarbeitungs- und Kommunikationsmodell charakterisiert werden. [BD10a] Den Kommunikationsmodellen widmet sich ein Teil des nächsten Unterkapitels und sie werden im Folgenden nicht mehr betrachtet.

Ereignisgesteuerte Architekturen basieren auf einem speziellen Verarbeitungsmodell, das aus den folgenden Hauptelementen besteht: Ereignisquelle, Ereignissenke und Ereignisobjekt.

Die Ereignisquelle ist die Komponente, die für die Aktivitäten, die im ersten Schritt stattfinden, zuständig ist: Erkennen der relevanten Informationen und Erzeugen der entsprechenden Ereignisobjekte. Sie bestimmt auch zu welchem Zeitpunkt die Ereignisse tatsächlich ausgelöst werden.

Als Ereignissenke wird wiederum eine Software-Komponente bezeichnet, die ein Ereignis empfängt und unmittelbar nachdem sie es empfangen hat, entsprechend reagiert. Diese führt also die Prozesse in Schritt 3 – Reaktion durch.

Das Ereignisobjekt spiegelt lediglich das tatsächliche Ereignis im System wider und enthält keine Informationen darüber, welche Operationen die Ereignissenke nach Empfang des Ereignisses ausführen wird. Die Logik, die beschreibt, wie auf ein Ereignis reagiert werden soll, kennt ausschließlich die Ereignissenke. Dies führt zu einer losen Kopplung der an der Interaktion beteiligten Software-Komponenten. [BD10a]

2.2.2 Schichten

Beim Entwurf einer Software-Architektur ist es immer wichtig, unterschiedliche logische Strukturierungsschichten abzugrenzen. Bei einer ereignisgesteuerten Architektur lassen sich drei logische Schichten unterscheiden: Ereignisquellenschicht, Ereignisverarbeitungsschicht und Ereignisbehandlungsschicht [BD10b].

Ereignisquellenschicht

Die Ereignisquellenschicht ist für den Ursprung der Ereignisse, also die Quellen, aus denen sie entstammen, vorgesehen. Die Ereignisquellen sind anwendungsspezifisch und können beispielsweise Sensoren, Benutzereingaben oder Software-Module sein. Auf dieser Schicht werden Signale von den Quellen empfangen und die entsprechenden Ereignisobjekte, welche die Ereignisse beschreiben und im System abbilden, erzeugt. Zu den Aufgaben dieser Schicht zählt auch die Weitergabe der Ereignisobjekte an die weiterverarbeitende Schicht. [BD10b]

Ereignisverarbeitungsschicht

Die Ereignisverarbeitungsschicht bekommt mehrere einzelne Ereignisobjekte oder Ströme von Ereignisobjekten als Eingabe und sorgt für ihre Analyse und Verarbeitung. Ein Ereignisstrom besteht aus einer Folge von kontinuierlich eintreffenden Ereignisobjekten, deren Anzahl entweder unbegrenzt oder begrenzt sein kann, zum Beispiel durch bestimmte Gruppierungskriterien. Auch heterogene Ereignisobjekte von unterschiedlichen Ereignisquellen können im Rahmen eines Ereignisstroms übertragen werden. Die Analyse der Eingaben erfolgt anhand Ereignisregeln, mit deren Hilfe Ereignismuster in einem Ereignisstrom erkannt werden können. Wenn Ereignismuster erkannt sind, dann kann in diesem Fall eine Kaskadierung von Ereignissen oder eine Weitergabe an die Behandlungsschicht stattfinden. Kaskadierung bedeutet, dass von den erkannten Ereignismustern neue komplexere Ereignisse generiert werden. Die Hauptaufgabe der Ereignisverarbeitungsschicht besteht somit darin, den Ereignistyp zu erkennen und das entsprechende Ereignis anzustoßen. [BD10b]

Ereignisbehandlungsschicht

Auf der Ereignisbehandlungsschicht findet anschließend die tatsächliche Ereignisbehandlung als Reaktion auf die erkannten Ereignismuster oder -typen statt. Die Reaktion ist immer anwendungsspezifisch und hängt vom Ereignistyp ab. Mögliche Reaktionen sind zum Beispiel: der Aufruf von Web Services, die Benachrichtigung von Benutzern oder das Publizieren von Ereignisnachrichten. [BD10b]

2.2.3 Vorteile

Die ereignisgesteuerte Architektur ist ein zentrales Konzept in der modernen Software-Entwicklung und bietet viele Vorteile, welche die Software-Qualität beeinflussen und im Folgenden diskutiert werden.

Aus dem ereignisgesteuerten Architekturstil ergeben sich folgende Qualitätseigenschaften einer Software: lose Kopplung und Skalierbarkeit der Software-Komponenten, Robustheit und Wartbarkeit, Agilität, Aktualität. [BD10c]

Lose Kopplung und Skalierbarkeit

Ereignisgesteuerte Architekturen erfüllen in idealer Weise die Voraussetzungen für eine gute Skalierbarkeit und erlauben eine lose Kopplung der Komponenten. Durch geeignete Kommunikationsmodelle und verteilte Ereignisverarbeitung ist eine Entkopplung der Systemkomponenten auf logischer und physikalischer Ebene möglich.

Robustheit und Wartbarkeit

Der hohe Grad der Entkopplung und die geringe Abhängigkeit zwischen den Komponenten erlauben es, lokale Änderungen am System ohne globale Auswirkungen an jeder Systemkomponente vorzunehmen. Dies garantiert eine gute Wartbarkeit, aber auch eine gewisse Widerstandsfähigkeit, da das System antwortbereit bleibt, auch wenn einzelne Komponenten ausfallen.

Agilität

Da die ereignisgesteuerte Architektur eine realitätsnahe und flexibel, an sich ständig ändernde Anforderungen, anpassbare Modellierung ermöglicht, kann eine hohe fachliche und technische Agilität erreicht werden. Neue Ereignistypen, Ereignisquellen und Systemkomponenten lassen sich in das bestehende System einfach integrieren. Daraus ergibt sich auch eine hohe Flexibilität und Anpassungsfähigkeit. [BD10c]

Aktualität

In einer ereignisgesteuerten Architektur werden Ereignisse erkannt und analysiert, sobald sie tatsächlich auftreten. Aus diesem Grund liefert diese Architekturart eine aktuelle Sicht auf den derzeitigen Status der Prozesse und ermöglicht eine Prozessüberwachung und -bewertung in Echtzeit. Daraus kann die Schlussfolgerungen gezogen werden, dass dieser Architekturstil auch Antwortbereitschaft als eine der Anforderungen des Reaktiven Manifests garantiert. [BD10c]

2.2.4 Nachteile

Den oben vorgestellten Vorteilen stehen allerdings einige Nachteile gegenüber, die aus den Eigenschaften einer ereignisgesteuerten Architektur als Folge hervorgehen. Beispiele dafür sind Redundanz, schlechte Testbarkeit und undurchsichtiger Kontrollfluss.

Redundanz

Die Ereignisorientierung und die sehr lose Kopplung können zur Folge haben, dass bestimmte Daten und Funktionalitäten redundant in mehreren Systemen enthalten sind. Bei Reduktion der Redundanz wächst automatisch die Abhängigkeit zwischen den Software-Komponenten und hiermit sinkt automatisch der Grad der Entkopplung. Dies führt zu einer erschwerten Wartbarkeit und Erweiterbarkeit und bei Änderungen – zu Inkonsistenzen, weil redundante Daten und Funktionen an mehreren Stellen nachgezogen werden müssen. [BD10c]

Schlechte Testbarkeit

Problemstellen und Fehler sind in verteilten Systemen mit lose gekoppelten Komponenten sehr schwer zu lokalisieren und beheben. Ein Beispiel dafür ist der Fall, wenn ein Ereignisempfänger überhaupt keine Ereignisse empfangen kann. Theoretisch existieren unendlich viele mögliche Gründe dafür, die tatsächliche Ursache ist allerdings sehr schwer zu bestimmen. Zum aktuellen Zeitpunkt existieren in der Praxis kaum zuverlässige Methoden zum Testen von Systemen mit ereignisgesteuerten Architekturen. [BD10c]

Undurchsichtiger Kontrollfluss

Aufgrund der Entkopplung der Komponenten von Systemen mit ereignisgesteuerten Architekturen ist es schwer, den Kontrollfluss des Systems effektiv zu verfolgen. Die Übersichtlichkeit geht insbesondere bei komplexeren Systemen schnell verloren und ein Gesamtverständnis über die Kontrolle des Systemverhaltens ist schwer zu bekommen. Dies erschwert die Systemanpassung und -erweiterung.

2.3 Nachrichtenorientierte Architektur

Moderne Software-Systeme stellen immer höhere Anforderungen an die Kommunikation zwischen den einzelnen Systemkomponenten. Bisher hat sich das Client/Server-Kommunikationsmodell in diversen Systemen durchgesetzt, es stößt aber in vielen Anwendungsfällen an seine Grenzen. Bei diesem Kommunikationsmodell kann ein vorübergehender Ausfall einer Komponente oder eines Web Service zu Blockierungen oder Datenverlusten führen. Überdies ist dieses klassische Paradigma kaum auf Anwendungen mit einer ereignisgesteuerten Architektur anwendbar. Nachrichtenorientierte Ansätze versuchen diese Probleme zu lösen. In den nachfolgenden Ausführungen wird das Konzept einer nachrichtenorientierten Architektur als eine der Anforderungen des Reaktiven Manifests erörtert, ihre Hauptelemente und Kommunikationsmodelle vorgestellt, sowie Vorteile und Schwachstellen diskutiert.

2.3.1 Hauptelemente

Jede nachrichtenorientierte Architektur besteht aus den folgenden Hauptelementen: Nachrichten, Nachrichtenproduzent, Nachrichtenkonsument und Nachrichtenserver, auch Nachrichten-Broker oder Message Bus genannt. [AS+09]

In einer Nachricht sind Daten, die von einer Software-Komponente zu einer anderen zu übertragen sind, enthalten [AS+09]. Wenn eine nachrichtenorientierte Architektur zusammen mit einer ereignisgesteuerten Architektur kombiniert wird, erfolgt meistens das Verschicken einer Nachricht als Reaktion auf das Eintreffen eines Ereignisses. In diesem Fall werden oft anhand der Nachricht auch Daten übertragen, diese Datenübertragung stößt allerdings einen bestimmten Prozess im System an.

In der Regel bilden zwei Teile die Struktur einer Nachricht: Header und Nutzdaten. Der Header beschreibt die Nachricht mit Hilfe von Metadaten, wie zum Beispiel: Typ der Nachricht, Priorität, Ablaufzeit. Der zweite Teil enthält die zu übertragenden Daten in einem beliebigen Format, beispielsweise JSON oder XML. [AS+09]

Der Nachrichtenproduzent und der Nachrichtenkonsument stellen die Kommunikationspartner in einer nachrichtenorientierten Architektur dar. Der Nachrichtenproduzent erzeugt die Nachricht, während der Nachrichtenkonsument diese empfängt. Die Kommunikationspartner können verschiedene Software-Komponenten oder komplette Anwendungen sein.

Normalerweise kommunizieren die Kommunikationspartner nicht direkt miteinander, sondern über einen Nachrichtenserver, der als Vermittler zwischen ihnen agiert. Der Nachrichtenproduzent sendet also seine Nachrichten nicht durchgehend an den Nachrichtenkonsumenten, sondern an den Nachrichtenserver, der sie dann dem Nachrichtenkonsumenten zustellt. [AS+09] Dieser Prozess wird Routing genannt. Es ist zu beachten, dass für eine Nachricht auch mehrere Konsumenten existieren können. Eine der Hauptaufgaben des Nachrichtenservers besteht in der Ermittlung aller Konsumenten einer Nachricht. Dabei kann es erforderlich sein, dass dieser den Nachrichtentyp und ggf. auch andere Metadaten einer Nachricht berücksichtigen muss, um festzulegen, welche Konsumenten die jeweilige Nachricht abonniert haben. In manchen Fällen muss der Nachrichtenserver Nachrichten in ein einheitliches Format überführen oder entsprechend modifizieren. [We12]

2.3.2 Kommunikationsmodelle

Es existieren mehrere Möglichkeiten zur Kommunikation zwischen den Komponenten einer nachrichtenbasierten Architektur, die im Folgenden erläutert werden.

Synchrone vs. asynchrone Kommunikation

Typisch für eine synchrone Kommunikation ist es, dass sie zu einer Blockierung führt. In diesem Fall ist der Nachrichtenproduzent blockiert, bis die Nachricht an den Nachrichtenkonsumenten komplett übermittelt worden ist. Im schlimmsten Fall kann der Nachrichtenproduzent sogar solange blockiert sein, bis der Nachrichtenkonsument die Nachricht vollständig abgearbeitet hat. [AS+09]

Bei einer asynchronen Kommunikation gibt es hingegen diese Probleme nicht. Das liegt daran, dass bei dieser Art der Kommunikation das Senden und Empfangen von Nachrichten zeitversetzt stattfinden und der Nachrichtenproduzent kann unmittelbar nach dem Verschicken der Nachricht mit der Verarbeitung von weiteren Prozessen fortfahren, ohne warten zu müssen.

Transiente vs. persistente Kommunikation

Es existiert auch eine weitere Unterscheidung nach transienter und persistenter Kommunikation. Bei einer transienten Kommunikation werden Nachrichten vom Produzenten zum Konsumenten zuverlässig übertragen, nur wenn beide Kommunikationspartner zum gleichen Zeitpunkt verfügbar sind, da Nachrichten im System nicht gespeichert werden. In allen anderen Fällen können Nachrichten verloren gehen. Bei einer persistenten Kommunikation dagegen ist eine garantierte Nachrichtenübermittlung möglich, da Nachrichten solange im System gespeichert werden, bis sie tatsächlich zum Konsumenten erfolgreich transportiert werden können. Somit gehen keine Nachrichten verloren, falls der Nachrichtenkonsument zum Zeitpunkt des Versendens der Nachricht nicht aktiv ist. [AS+09]

Message Queueing

Bei diesem Modell erfolgt die Kommunikation mittels Warteschlagen, die sich auf dem Nachrichtenserver befinden. Wenn ein Nachrichtenproduzent eine Nachricht erzeugt, wird diese in einer Warteschlange gespeichert und bleibt dort bis sie dem Nachrichtenkonsumenten erfolgreich zugestellt wird, auch im Fall wenn er vorübergehend nicht verfügbar ist. Im Fall eines Ausfalls des Konsumenten existieren mehrere mögliche Vorgehensweisen. Eine Möglichkeit ist, dass sich der Nachrichtenkonsument beim Nachrichtenserver meldet, wenn er wieder verfügbar ist, um verpasste Nachrichten zugestellt zu bekommen. Die alternative Lösung besteht darin, dass der Nachrichtenserver periodisch versucht, den Konsumenten zu erreichen. Durch Message Queueing wird eine persistente Kommunikation erreicht. [AS+09]

Punkt-zu-Punkt-Kommunikation

Bei einer Punkt-zu-Punkt-Kommunikation wird das Modell des Message Queueing benutzt. Jedem Nachrichtenkonsumenten wird eine Warteschlage zugeordnet und sobald ihn die Nachricht erreicht, verschwindet diese aus der Warteschlange und kann nicht mehr abgerufen werden [AS+09]. Die Übertragung der Nachricht von der Warteschlange zum Nachrichtenkonsumenten kann der Nachrichtenserver oder der Konsument selber anstoßen. Es zu beachten, dass bei diesem Kommunikationsmodell die Nachricht an einen einzigen Nachrichtenkonsumenten übermittelt wird und an mehrere.

Publish/Subscribe

Im Gegensatz zum Punkt-zu-Punkt.Modell ermöglicht der Publish/Subscribe-Ansatz die Verteilung einer Nachricht an mehrere Konsumenten. Dafür müssen ein oder mehrere Nachrichtenkonsumenten ein bestimmtes Thema, das meistens ein bestimmtes Ereignis ist, abonnieren. Unmittelbar nachdem der Nachrichtenproduzent eine Nachricht zu diesem Thema oder Ereignis veröffentlicht hat, bekommen alle Abonnenten eine Kopie dieser Nachricht. [AS+09] Dieser Ansatz wird oft mit dem Modell des Message Queueing kombiniert, da ansonsten unter ungünstigen Umständen keine Kopie der Nachricht erhalten werden kann, zum Beispiel wenn ein Konsument zum Zeitpunkt des Versendes der Nachrichten nicht aktiv ist. Das Publish/Subscribe-Prinzip wird oft in Systemen mit einer ereignisgesteuerten Architektur eingesetzt.

2.3.3 Vorteile

Der Ansatz einer nachrichteorientierten Architektur, die auch eine der im Reaktiven Manifest definierten Anforderungen ist, bringt folgende Vorteile mit sich: lose Kopplung, hohe Flexibilität und blockierungsfreies Verhalten.

Lose Kopplung

Der größte Vorteil einer nachrichtenorientierten Architektur ist der hohe Grad an Entkopplung zwischen ihren Komponenten. Bei diesem Architekturparadigma existieren hauptsächlich zwei Arten von Entkopplung: zeitliche und räumliche Entkopplung [AS+09].

Zeitliche Entkopplung bedeutet, dass der Nachrichtenproduzent und der Nachrichtenkonsument nicht zur gleichen Zeit an der Interaktion beteiligt sein müssen. Es ist vollkommen akzeptabel, dass keiner der Nachrichtenkonsumenten aktiv ist, während der Nachrichtenproduzent seine Nachricht versendet. Andererseits muss der Nachrichtenproduzent nicht unbedingt verfügbar sein, während die Nachrichtenkonsumenten seine Nachricht empfangen. [AS+09]

Mit räumlicher Entkopplung ist gemeint, dass sich die Kommunikationspartner nicht unbedingt kennen müssen. Daher muss der Nachrichtenproduzent nicht auf jeden Fall wissen, welche Nachrichtenkonsumenten seine Nachrichten abonniert haben. Es ist auch nicht erforderlich, dass die Konsumenten den Produzenten kennen. [AS+09]

Hohe Flexibilität

Bei dieser Architekturart ist es sehr einfach, neue Prozesse zu integrieren. Um dies zu erreichen, ist es nur notwendig, die Architektur um die neuen Kommunikationspartner und ggf. um die neuen Nachrichten zu erweitern. Bestehende Komponenten müssen in den meisten Fällen nicht modifiziert werden. Überdies können diverse Kommunikationsmodelle verwendet werden. Jede nachrichtenorientierte Architektur kann auch in idealer Weise mit einer ereignisgesteuerten Architektur zusammengestellt werden.

Blockierungsfreies Verhalten

Dank der asynchronen Kommunikation zwischen den Komponenten einer nachrichtenorientierten Architektur kann es zu keiner Blockierung kommen, auch wenn eine oder mehrere Komponente nicht verfügbar oder ausgefallen sind. Diese Eigenschaft verbessert wesentlich die Benutzererfahrung und garantiert hohe Flexibilität.

2.3.4 Nachteile

Trotz der vielen Vorteile haben nachrichtenorientierte Architekturen auch einige Schwachstellen. Der größte Nachteil ist die starke Abhängigkeit von einer zentralen Komponente, dem Nachrichtenserver. Die Performanz wird von ihm stark beeinflusst und wenn er ausfällt, ist die Nachrichtenübertragung nicht mehr möglich. Weitere Schwachstellen sind, ähnlich wie bei den ereignisgesteuerten Architekturen - die schlechte Testbarkeit und die schwierige Entdeckung von Fehlern. Das liegt an der Entkopplung der Komponenten und der daraus resultierenden schweren Verfolgung des Kontrollflusses im System. Ein weiterer Nachteil solcher Systeme ist ihre Komplexität. Der Aufbau und die praktische Umsetzung von nachrichtenorientierten Software-Systemen sind wegen der starken Entkopplung der einzelnen Komponenten relativ komplex.

2.4 Microservices

Microservices stellen eine zentrale Technik zum Modularisieren von Software-Systemen dar, die versucht, die Nachteile großer monolithischer Systeme zu überwinden. In diesem Unterkapitel erfolgen eine Definition von Microservices samt ihren grundlegenden Eigenschaften, eine Vorstellung von möglichen Deployment-Strategien, sowie eine kurze Bewertung des Konzepts.

2.4.1 Definition

Microservices sind kleine Einheiten, die auch als Software-Komponenten bezeichnet werden, haben eine eigene Ablaufplattform, verfügen über einen eigenen Programmablauf und kommunizieren mit anderen Microservices über ein Netzwerk. Sie sind klein, weil sie eine bestimmte Funktionalität fokussieren und diese mit Hilfe von definierten Schnittstellen nach außen zur Verfügung stellen. Der Grad der Unabhängigkeit von Microservices ist so hoch, dass sie in unterschiedlichen Programmiersprachen implementiert und vollkommen getrennt deployed werden können. Die Persistenzmechanismen sind auch als Teil eines Microservices zu betrachten. Ein Microservice enthält normalerweise nur zusammenhängende Funktionen, sodass Änderungen immer nur einen einzigen Microservice betreffen und nicht das Gesamtsystem. [Ti15]

Aus dieser Definition ergibt sich der Begriff der Microservices-Architektur, die als ein Architekturparadigma bezeichnet wird, bei dem ein Software-System aus vielen kleinen unabhängigen Microservices aufgebaut ist. Dabei sind die einzelnen Microservices als Software-Komponenten zu betrachten, die unabhängig voneinander angepasst, weiterentwickelt und ausgetauscht werden können.

2.4.2 Grundlegende Eigenschaften

Microservices und die Microservices-Architektur besitzen folgende grundlegende Eigenschaften: Autonomie und Isolation, Elastizität, Widerstandsfähigkeit und Antwortbereitschaft, Nachrichtenorientierung, Konfigurierbarkeit [Fa15]. Daraus folgt, dass Microservices ein bewährtes Konzept sind, da sie alle vier Anforderungen des Reaktiven Manifests erfüllen.

Autonomie und Isolation

Microservices existieren und funktionieren vollkommen unabhängig. Konzeption, Entwicklung, Testen und Deployment erfolgen autonom. Sie sind zeitlich und räumlich isoliert. Microservices, die die Architektur einer Anwendung bilden, müssen nicht unbedingt innerhalb der gleichen Ablaufumgebung laufen und zeitgleich aktiv sein. [Fa15]

Elastizität, Widerstandsfähigkeit und Antwortbereitschaft

Microservices sind flexibel genug und skalierbar, sodass sie in sehr vielen verschiedenen Szenarien und Anwendungsfällen zum Einsatz kommen können. Damit diese Elastizität erreicht werden kann, muss auch die Deployment-Plattform bestimmte Mechanismen zu dynamischer Allokation von Ressourcen unterstützen. [Fa15] Die starke Entkopplung, die jede Microservices-Architektur aufweist, garantiert eine gewisse Widerstandsfähigkeit des Gesamtsystems, da auch wenn einzelne Microservices ausfallen, das System weiterhin antwortbereit bleiben kann. Antwortbereitschaft wird dadurch gewährleistet, dass ein Microservice immer eine spezielle Funktionalität fokussiert. Aus diesem Grund ist eine sehr schnelle Reaktion auf bestimmte Eingaben möglich.

Nachrichtenorientierung

Bei der Microservices-Architektur handelt es sich um ein Architekturmodell, bei dem separate Systeme (Microservices) in eine gemeinsame Plattform eingebettet werden und meistens mittels Nachrichten miteinander kommunizieren. Microservices besitzen eine Schnittstellenspezifikation, die bestimmt, wie mit ihnen interagiert werden kann. Diese Schnittstellenspezifikation definiert Endpunkte, über die der Aufruf der Funktionen eines Microservices möglich ist, sowie das Format der Nachrichten, die übertragen werden. [Fa15]

Konfigurierbarkeit

Eines der Ziele von Microservices ist die Wiederverwendbarkeit. Sie werden so konzipiert und entwickelt, dass sie in verschiedenen anwendungsspezifischen Szenarien entsprechend konfiguriert und sinnvoll eingesetzt werden können. Microservices stellen somit nicht einfach eine öffentliche Schnittstelle bereit, sondern mehrere und verwalten Zugriffsrechte auf unterschiedlichen Ebenen. [Fa15]

2.4.3 Deployment-Strategien

Jedes Software-System mit einer Microservices-Architektur besteht aus mehreren Microservices, die auf verschiedene Technologien basieren können und bestimmte Anforderungen an die Ablaufplattform stellen. Es existieren mehrere Möglichkeiten zum Deployment von Microservices.

Eine Möglichkeit ist das Deployment von mehreren Microservice-Instanzen pro Host. In diesem Fall werden eine oder mehrere physikalische oder virtuelle Maschinen (VM) benutzt und mehrere unterschiedliche Microservice-Instanzen auf jeder dieser Maschinen installiert. [Ri16] Dies ist auf Abbildung 3 dargestellt, wo n Instanzen von drei Microservices auf n Hostmaschinen deployed sind.

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 3: Deployment von mehreren Microservice-Instanzen pro Host

Eine andere Alternative ist das Deployment von einer Microservice-Instanz pro Host. In diesem Fall ist jede Microservice-Instanz auf einem eigenen Host deployed und von anderen Microservice-Instanzen isoliert. Diese Deployment-Strategie hat zwei Spezialfälle: Deployment von einer Microservice-Instanz pro virtuelle Maschine und Deployment von einer Microservice-Instanz pro Container. [Ri16]

Im ersten Spezialfall wird jeder Microservice in ein VM-Image gepackt und jede Microservice-Instanz ist praktisch eine virtuelle Maschine, die anhand dieses VM-Images gestartet wird. Diese Deployment-Strategie ist auf Abbildung 4 grafisch dargestellt, wo drei Instanzen eines Microservices deployed sind. [Ri16]

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 4: Deployment von einer Microservice-Instanz pro virtuelle Maschine

Im zweiten Spezialfall läuft jede Microservie-Instanz in einem eigenen Container. Durch Container wird eine Virtualisierung auf Betriebssystemebene erreicht. In einem Container sind ein oder mehrere Prozesse enthalten. Bei dieser Deployment-Strategie wird jeder Microservice in ein Container-Image gepackt und jede Microservice-Instanz als Container deployed. Normalerweise laufen mehrere Container auf einer physikalischen oder virtuellen Maschine. Der Prozess ist auf Abbildung 5 dargestellt. [Ri16]

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 5: Deployment von einer Microservice-Instanz pro Container

2.4.4 Vorteile

Die grundlegenden Eigenschaften von Microservices repräsentieren auch ihre Vorteile. Dazu zählen noch lose Kopplung der Microservices-Architektur, technologische Heterogenität, hohe Performanz, Wiederverwendbarkeit, Robustheit, Skalierbarkeit.

Da viele autonome Microservices die Software-Architektur bilden, sind die einzelnen Software-Komponenten entkoppelt. Eine der größten Vorteile ist die technologische Heterogenität, die es erlaubt, die einzelnen Microservices in vollkommen unterschiedlichen Programmiersprachen und mithilfe diverser Frameworks zu entwickeln. Jeder Microservice ist auf eine bestimmte Funktionalität konzentriert, was eine hohe Performanz ermöglicht. Überdies können mehrere Microservice-Instanzen erzeugt und in verschiedenen anwendungsspezifischen Kontexten wiederverwendet werden. Robustheit bedeutet, dass wenn ein Microservice ausfällt, nur eine bestimmte Funktion nicht mehr zur Verfügung steht. Das System kann weiterhin stabil bleiben. Wenn mehrere Instanzen eines Microservices existieren, kann auch Widerstandsfähigkeit garantiert werden. Noch ein großer Vorteil ist die unabhängige Skalierbarkeit von Microservices. Bei zu hoher Last können leicht neue Microservice-Instanzen gestartet werden, die sich diese Last teilen [Ti15]. Bei einer monolithischen Software-Architektur ist das nicht möglich.

2.4.5 Nachteile

Zu den Schwachstellen von Microservices zählen folgende Aspekte: hohe Anforderungen an die Ablaufplattform, aufwendiges Testen, komplizierte Service Discovery.

Hohe Anforderungen an die Ablaufplattform

Microservices stellen relativ hohe Anforderungen an ihre Laufzeitumgebung. Sie muss dynamische Allokation von Ressourcen in Abhängigkeit von der Last unterstützen und hohe Verfügbarkeit aufweisen. Außerdem muss die Ablaufplattform Möglichkeiten zur Isolation der einzelnen Microservices bieten, zum Beispiel durch Deployment von einer Microservice-Instanz pro Container.

Aufwendiges Testen

Microservices erfordern einen aufwändigen Testprozess. Einerseits müssen alle internen Funktionen (zum Bespiel zu Datenzugriff und -verarbeitung) getestet werden, andererseits aber auch die öffentlichen Schnittstellen, die Microservices nach außen zur Verfügung stellen. Überdies sind bestimmte Integrationstests erforderlich, die sicherstellen, dass ein Microservice in Kollaboration mit anderen richtig funktioniert. Die Skalierbarkeit und die Elastizität eines Microservices, sowie seine Fähigkeit, sich nach einem Ausfall wiederherzustellen, sind auch zu testen. [Fa15]

Komplizierte Service Discovery

Die Service Discovery ist ein sehr wichtiger Aspekt in der Microservices-Architektur. Nachdem die Microservices deployed worden sind, müssen sie mithilfe geeigneter Techniken vom Client lokalisiert werden. Im einfachsten Fall kann die Aufrufadresse eines Microservices clientseitig hardcoded werden, was allerdings häufig eine schlechte Lösung ist, da bei Änderungen in dieser Aufrufadresse das Software-System nicht mehr funktionieren kann. Daher empfiehlt es sich, andere komplexere Techniken zur dynamischen Service Discovery zur Laufzeit einzusetzen.

2.5 REpresentational State Transfer (REST)

REST ist ein Architekturparadigma, das festlegt, wie unter Verwendung existierender Internetprotokolle das Konzept der Web Services möglichst einfach umgesetzt werden kann. Bei REST erfolgt der Zugriff auf Ressourcen mittels einer URL. Ressourcen sind in der Regel Daten, die in einem beliebigen Format (meistens JSON oder XML) strukturiert sind und mit Hilfe eines Identifikators, dem Uniform Resource Identifier (URI), von anderen Ressourcen eindeutig unterschieden werden. [Me10]

In diesem Unterkapitel erfolgen eine Erläuterung der REST-Architektur und ihrer Komponenten, sowie eine Vorstellung der Methoden zur Verwaltung von Ressourcen, die in der REST-Architektur eine Anwendung finden.

2.5.1 Architektur

In der REST-Architektur existieren drei Gruppen von Architekturelementen: Datenelemente, Connectors und REST Components.

Datenelemente

Die Datenelemente sind Ressourcen, die ein wichtiger Aspekt von der REST-Architektur darstellen, da sie zwischen den REST Components ausgetauscht werden. Sie besitzen eine Repräsentation, die aus einer Bytesequenz und Metadaten besteht. Die Bytesequenz repräsentiert ihren Inhalt und die Metadaten beschreiben diesen Inhalt. Das Format der Datenelemente ist nicht fest vorgegeben, allerdings müssen alle REST Components es kennen und in der Lage sein, Daten in diesem Format zu verarbeiten. [Ja05]

Connectors

Die Connectors verwalten die Kommunikation zwischen den REST Components und sind abstrakte Schnittstellen, welche die Funktionen der REST Components während der Interaktion beschreiben. Typisch für REST ist die Zustandslosigkeit. Das bedeutet, dass jede REST-Anfrage alle Informationen enthalten muss, die notwendig sind, damit der Connector die Anfrage verstehen kann, unabhängig von anderen Anfragen. [Ja05] Aus diesem Grund ist jede Anfrage in sich geschlossen und das ermöglicht eine Verteilung der Anfragen auf unterschiedliche Server, da keine Zustandshaltung serverseitig erforderlich ist.

Bei der REST-Architektur existieren folgende Connector-Typen: Client, Server, Cache, Resolver und Tunnel Connectors. Der Client Connector sendet Anfragen und bekommt Antworten. Der Server Connector dagegen wartet auf Anfragen und liefert Antworten zurück. Der Cache Connector speichert vorübergehend Ressourcen client- oder serverseitig, die oft angefragt werden, um eine schnelle Auslieferung zu ermöglichen. Der Resolver Connector bildet einen Ressourcenidentifikator auf eine Internetadresse ab. Der Tunnel Connector leitet Anfragen weiter. Die REST Components implementieren normalerweise einen oder mehrere Connector-Typen. [Ja05]

REST Components

Die REST Components werden anhand ihrer Rolle in der Interaktion identifiziert. Es wird unterschieden zwischen den folgenden REST Components: User Agent, Origin Server und Middleware. Der User Agent benutzt einen Client Connector, um eine Anfrage zu initiieren und bekommt bestimmte Datenelemente als Antwort zurück. Der Origin Server benutzt einen Server Connector, um die vom User Agent initiierte Anfrage zu bekommen und stellt eine öffentliche Schnittstelle zu seinen Diensten zur Verfügung. Die Middleware kann verschiedene Connector-Typen implementieren. Sie kann beispielsweise sowohl als Client, als auch als Server agieren und die Client-Anfragen bzw. die Server-Antworten entsprechend transformieren. [Ja05]

Der größte Vorteil der REST-Architektur besteht in der Entkopplung von Client und Server. Die interne Struktur der Dienste, die der Server mittels öffentlicher Schnittstellen bereitstellt, bleibt für den Client versteckt und diese Dienste können als Microservices betrachtet werden. Überdies kann bei einer REST-Architektur hohe Performanz durch Lastverteilung garantiert werden, da aufgrund der Zustandslosigkeit keine Zustandshaltung serverseitig erforderlich ist und verschiedene Anfragen vom gleichen Client auf unterschiedliche Server verteilt und parallel abgearbeitet werden können.

2.5.2 Methoden

Der HTTP-Standard definiert eine Menge von Methoden, mit deren Hilfe Datenelemente oder Ressourcen in einer REST-Architektur verwaltet werden können. Bei der Implementierung einer REST-Schnittstelle kommen immer die Methoden GET, PUT, POST und DELETE zum Einsatz. Es existieren auch zusätzliche Methoden wie HEAD, TRACE, CONNECT und OPTION, die im Folgenden nicht betrachtet werden. [TE+15]

Mit Hilfe der GET-Methode werden Datenelemente, die durch einen URI identifiziert werden, beim Server angefragt und auf dem Client bekommen. HEAD funktioniert ähnlich wie GET. Der Unterschied ist, dass HEAD nur die Metadaten des Elements ohne die eigentlichen Daten zurückliefert. PUT ist die inverse Operation zu GET. Mittels dieser Methode ist eine Aktualisierung bestehender und durch einen URI identifizierter Datenelemente oder Ressourcen möglich oder wenn das Datenelement nicht existiert, wird es dabei erzeugt. Der Client benutzt den Entity Body der HTTP-Anfrage, um die Informationen zum Server zu übermitteln. [TE+15]

Die POST-Methode hat zwei Grundfunktionen. Einerseits dient sie zum Anlegen eines neuen Datenelements unter einem vom Server bestimmten URI, andererseits wird sie für alle anderen Operationen verwendet, für die keine der übrigen Methoden geeignet ist. Logischerweise ist DELETE für das Löschen von Datenelementen zuständig. [TE+15]

2.6 Web Components

Web Components sollen die Entwicklung wiederverwendbarer Komponenten auf der Repräsentationsebene einer Web-Anwendung und ihre Einbindung über selbst definierte Tags im HTML-Code ermöglichen. Die Web-Auszeichnungssprache HTML bietet zum heutigen Zeitpunkt keine standardisieren Möglichkeiten zur Erstellung wiederverwendbarer Web Components, die von allen Browsern unterstützt werden [CIU-WC]. Es existieren allerdings vier vom World Wide Web Consortium (W3C) festgelegte Spezifikationen, die Web Components und ihre API definieren. Das Ziel dieser Spezifikationen ist eine systematische und einheitliche Entwicklung eigener Web Components. [Ac14]

Das W3C definiert folgende vier Spezifikationen: Shadow Document Object Model (DOM), Custom Elements, HTML Templates und HTML Imports.

Shadow DOM

Bei der Einbindung von Custom Elements oder externen GUI-Komponenten gibt es immer das Problem, dass das DOM dieser Komponenten im Rest des DOM-Baums, in dem sie vorkommen, gekapselt ist. Dies führt zu vielen Kollisionen wie zum Beispiel zu Namenskonflikten bei den einzelnen CSS-Klassen oder zu doppelten IDs im DOM. [Ac14]

Das Shadow DOM soll dieses Problem lösen, indem es die Definition lokaler DOM-Bäume möglich macht, in denen die Custom Elements gekapselt und vom globalen DOM isoliert werden. [Ha16] Derzeit unterstützen nur Google Chrome und Opera vollständig das Shadow DOM [CIU-WC].

Custom Elements

Custom Elements ermöglichen die Entwicklung und Definition eigener HTML-Elemente mit spezifischen Eigenschaften und ihre Wiederverwendung an mehreren Stellen im HTML-Code. In ihrem Namen muss unbedingt ein Bindestrich vorkommen, damit eine eindeutige Unterscheidung von den bestehenden HTML-Elementen möglich ist. Custom Elements müssen auch über eine eigene Anwendungslogik verfügen, die beispielsweise in mehrere separate Methoden ausgelagert ist, und in der Lage sein, auf bestimmte Ereignisse entsprechend zu reagieren. Ihre spezifischen Eigenschaften können durch Custom Attributes definiert werden. [Ac14] Zum derzeitigen Zeitpunkt bieten die meisten aktuellen Browser keine vollständige native Unterstützung für dieses Feature [CIU-WC].

HTML Templates

HTML Templates sind mittlerweile Teil des HTML5-Standards und werden von allen gängigen Browsern unterstützt [CIU-WC]. Diese Spezifikation wird durch das Template-Element <template> in HTML5 praktisch umgesetzt und dient zur Definition von HTML-Vorlagen, die an mehreren Stellen wiederverwendet werden können. Die Inhalte vom Template-Element werden beim Laden der Seite zwar geparst, um ihre Validität zu überprüfen, aber nicht gerendert und visualisiert. Die Idee dabei ist, dass die Inhalte innerhalb des Template-Elements dynamisch zur Laufzeit in das DOM geladen und visualisiert werden. Dieses dynamische Laden erfolgt mithilfe der entsprechenden JavaScript-Funktionen, welche die API zur Verfügung stellt und wird in der Regel durch bestimmte Benutzereingaben angestoßen. HTML Templates bieten den Vorteil, HTML-Fragmente deklarativ zu definieren und diese dynamisch mittels JavaScript in das DOM einzubauen. Vor ihrer Einführung war das nur über Umwege möglich, wie zum Beispiel durch Verstecken der entsprechenden HTML-Elemente mittels CSS und Einblenden durch Anpassung des Styles des HTML-Elements zur Laufzeit in JavaScript. [Ac14]

HTML Imports

HTML Imports sollen das Einbinden von HTML-Dokumenten innerhalb anderer HTML-Dokumente ermöglichen. Das soll ähnlich wie das Einbinden von CSS-Dateien und externe Scripts funktionieren. Im Gegensatz zu iframe-Elementen werden HTML Imports in das DOM geladen aber genauso wie HTML Templates nicht automatisch visualisiert. Diese Technik ermöglicht eine Wiederverwendung und eine leichtere Wartbarkeit der einzelnen HTML-Komponenten. [Ac14]

Web Components stellen einen Fortschritt in der Entwicklung von Web-Anwendungen dar, indem sie die Entwicklung separater, wiederverwendbarer Einheiten samt ihrem Verhalten, die auf der Repräsentationsebene eingebunden werden, ermöglichen. Sie bieten viele Vorteile wie Wiederverwendbarkeit, erleichterte Wartbarkeit, Skalierbarkeit, Flexibilität. Allerdings unterstützen nur wenige Browser wie Google Chrome und Opera Web Components nativ [CIU-WC].

2.7 Angular 2

Obwohl die meisten aktuellen Browser keine vollständige native Unterstützung von Web Components bieten, existieren Web Frameworks, welche die Entwicklung und Einbindung von Web Components ermöglichen. Diese Web Frameworks setzen die vom W3C festgelegten Web Components-Spezifikation um und werden Polyfill Frameworks genannt. Beispiele dafür sind Angular 2, Google Polymer und ReactJS. Der Fokus dieses Unterkapitels liegt auf den Konzepten von Angular 2 für TypeScript. Zunächst werden die Grundprinzipien von TypeScript und Angular 2 vorgestellt. Anschließend erfolgt auch ein Vergleich zwischen den drei Web Frameworks.

2.7.1 TypeScript

Angular 2 existiert in drei Versionen – Angular 2 für JavaScript, für TypeScript und für Dart. TypeScript ist eine neue von Microsoft entwickelte und von den aktuellen objektorientierten Programmiersprachen wie Java und C# beeinflusste Programmiersprache, die nach JavaScript kompiliert wird und eine bessere und logische Strukturierung des Codes ermöglicht.

TypeScript ist eine Obermenge von JavaScript, was bedeutet, dass jeder gültige JavaScript-Code auch gültiger TypeScript-Code ist. JavaScript besitzt ein schwaches, dynamisches Typsystem. Im Gegensatz dazu müssen in TypeScript der Typ jeder Variable und der Typ des Rückgabewertes jeder Funktion explizit angegeben werden. TypeScript unterstützt folgende Datentypen: boolean, number, string, enum und any. Zusätzlich kann void als Typ des Rückgabewertes einer Funktion benutzt werden. Eine Variable vom Typ any ist nicht typisiert und kann Werte von jedem beliebigen Typ annehmen. Arrays und Tupel, sowie Objekte können auch deklariert werden. TypeScript bietet drei Möglichkeiten zur Deklaration einer Variable: mittels der Schlüsselwörter var, let und const. Variablen, die mittels var deklariert werden, haben einen Function Scope, mittels let – einen Block-Scope und const-Variablen besitzen auch einen Block-Scope, können aber nicht umdefiniert werden. [MS-TSD]

TypeScript ermöglicht auch die Festlegung einer vorgegeben Struktur eines Datenobjekts mit Hilfe von Interfaces. Ein Interface kann Attribute mit ihrem Typ aber auch Signaturen von Funktionen enthalten. Es besteht auch die Möglichkeit, optionale Attribute zu deklarieren. Interfaces können von anderen Interfaces und auch sogar von Klassen erben und von Klassen implementiert werden. Klassen funktionieren in TypeScript genauso wie in objektorientierten Programmiersprachen, wie beispielsweise Java. Anhand der Schlüsselwörter get und set erfolgt die Definition von Getter- und Setter-Funktionen, mit deren Hilfe ein Zugriff auf private Attribute einer Klasse außerhalb dieser Klasse möglich ist. In TypeScript werden auch Generics unterstützt. [MS-TSD]

In TypeScript gibt es auch das Konzept der Module. Module sind Komponenten, die ein eigenes Scope besitzen und nicht im globalen Scope ausgeführt werden. Klassen, Variablen, Funktionen, die im Rahmen eines Moduls deklariert sind, sind außerhalb des Moduls nicht sichtbar. Damit sie nach außen sichtbar werden, müssen sie mit dem Schlüsselwort export exportiert werden. Dann können sie mit import in den Client Code eingebunden werden. Außerdem bietet TypeScript eine weitere Möglichkeit zur besseren Strukturierung des Codes mit Hilfe von Namespaces oder Namensräumen. Innerhalb eines Namensraums können Module mit einem eindeutigen Namen definiert werden. Die gleichen Namen der Module können dann in einem anderen Namensraum verwendet werden. [MS-TSD]

2.7.2 Grundkonzepte

Angular 2 ist auf die komponentenbasierte Entwicklung von Web-Anwendungen fokussiert. Die Entwicklung eigener Web Components erfolgt in Angular 2 in wenigen Schritten. Zuerst werden Angular 2-Kernmodule importiert, die als Grundlage für die eigene Web Component dienen. Danach wird eine Klasse erstellt und mit der @Component-Annotation, die ein JSON-Objekt als Parameter bekommt, annotiert. Die Eigenschaft template des JSON-Objekts wird benutzt, um das HTML-Template der Web Component zu definieren. Bei komplexeren Web Components kann der HTML-Code in eine separate HTML-Datei ausgelagert und über die Eigenschaft templateUrl eingebunden werden. Der nächste Schritt ist die Festlegung eines Selektors mithilfe der Eigenschaft selector, durch den die Verwendung der Web Component im HTML-Code möglich ist, zum Beispiel selector: „my-component“. Optional können CSS-Klassen für die Web Component mittels der Eigenschaft style definiert werden. Diese CSS-Klassen beziehen sich nur auf diese Web Component und kollidieren nicht mit anderen CSS-Klassen. Somit setzt Angular 2 auch die DOM Shadow-Spezifikation um. In der Klasse selbst erfolgt die Definition der Eigenschaften und des Verhaltens der Web Component durch Attribute und Funktionen. Zum Schluss wird der Modul mittels des Schlüsselworts export nach außen sichtbar gemacht, damit die Web Component überall in der Anwendung verwendet werden kann. Angular 2 ermöglicht auch die Steuerung einer Web Component während der unterschiedlichen Phasen ihres Lebenszyklus mittels API-Funktionen wie ngOnInit(), ngOnDestroy(), ngAfterViewInit(). [Bö16]

In Angular 2 existieren viele Möglichkeiten, Eigenschaften eines Elements oder Web Components dynamisch zu definieren oder auf bestimmte Ereignisse entsprechend zu reagieren. Auf alle nativen Ereignisse, welche die DOM API zur Verfügung stellt, kann eine Reaktion in Angular 2 definiert werden. Auch eigene Ereignisse für eine Web Component können definiert werden. Überdies können die Werte aller nativen oder selbst definierten Attribute jedes HTML-Elements oder jeder Web Component dynamisch zur Laufzeit gesetzt werden. [Bö16]

Die Datenbindung ist ein Mechanismus zur einfachen und konsistenten Darstellung von Daten und stellt somit eine wichtige Anforderung an jedes moderne Web Framework. In Angular 2 gibt es zwei Arten von Datenbindung: Ein-Weg-Datenbindung und Zwei-Wege-Datenbindung. Bei der Ein-Weg-Datenbindung erfolgt der Datenfluss nur in einer Richtung – von der Parent-Komponente zur Child-Komponente. Bei einer Zwei-Wege-Datenbindung fließen Daten in beide Richtungen. Änderungen der Daten auf der einen Seite werden automatisch auf die andere Seite übertragen.

In Angular 2 existieren die sogenannten Expressions, die es erlauben, Daten zu manipulieren und zu kombinieren. Ein Beispiel dafür ist Umwandlung von Zeichenketten in Großbuchstaben oder Ausgabe in Abhängigkeit von einer Bedingung, zum Bespiel {{ text.length > 5 ? „a“ : „b“ }}. Pipes sind Filter, die Transformationen von Daten in Expressions ermöglichen. Angular 2 bietet eine Menge von vordefinierten Pipes wie zum Beispiel CurrencyPipe zur Währungsformatierung oder DatePipe zur Datumsformatierung. In diesem Beispiel wird die Zahl als Euro formatiert und das Euro-Symbol angezeigt: {{ 1.50 | currency: ‚EUR‘:true }}. Die Erstellung eigener Pipes ist auch sehr einfach, indem eine Klasse das Interface PipeTransform implementiert und mit der Annotation @Pipe annotiert wird. [Bö16]

Widerverwendbare Funktionalitäten von der Programmlogik können in Angular 2 Services ausgelagert werden. Ein Angular 2 Service ist eine Klasse, die mit der Injectable-Annotation annotiert werden soll und wird durch Dependency Injection in andere Teile der Web-Anwendung importiert. Es existieren zwei Arten von Services – globale und lokale Services. Globale Services sind Singletons mit einer einzigen Service-Instanz, die überall in der Anwendung verwendet wird. Bei lokalen Services dagegen wird eine neue Service-Instanz für jede Komponente, in der dieser Service benutzt wird, erzeugt. Services werden oft in Web Components durch Dependency Injection injiziert. Dafür ist eine Angabe der Abhängigkeiten von Services über die Eigenschaft providers der @Component-Annotation erforderlich. Die Erzeugung einer Service-Instanz erfolgt dann beim Erstellen der Web Component. Dabei handelt es sich um eine lokale Service-Instanz. Anschließend wird der Service in die Klasse der Web Component durch Dependency Injection geladen. Wenn eine Service-Instanz global, also anwendungsweit verfügbar sein soll, erfolgt die Erzeugung der Service-Instanz in der Haupt-Web-Component der Web-Anwendung. [Bö16]

Zur Kommunikation mit Web Services, die auf dem HTTP-Protokoll basieren, zum Bespiel mit REST-Schnittstellen, bietet Angular 2 einen HTTP Service, der in einem eigenen Service verwendet werden kann. Die Kommunikation mit einem Web Server ist asynchron und bei jeder Server-Anfrage liefert der Angular 2 HTTP Service ein sogenanntes Observable zurück, das mit der RxJS-Bibliothek erzeugt wird. Observables funktionieren ähnlich wie Promises in JavaScript. Wenn der Programmcode des Observables abgeschlossen ist, wird praktisch ein Ereignis ausgelöst und alle Abonnenten darüber informiert. Die Observable-Funktion subscribe() muss aufgerufen werden, um ein Observable zu abonnieren. Diese Funktion hat eine Callback-Funktion als Parameter, welche die angeforderten Daten vom Server als Argument bekommt. [Bö16]

2.7.3 Vergleich zu anderen Web Frameworks

Angular 2, Google Polymer und ReactJS sind zwar drei Frameworks, welche die Entwicklung eigener Web Components möglich machen, sie unterschieden sich aber in gewissen Aspekten und im Umfang der Funktionen, die sie zur Verfügung stellen.

Angular 2 ist ein komplettes Web Framework, das neben der Möglichkeit zur Entwicklung von Web Components auch viele andere Services, Funktionen und Mechanismen zur Anbindung von Services, Navigation in der Anwendung, Filterung und Manipulation von Daten bereitstellt. Mit Angular 2 kann eine produktive Enterprise Web-Applikation ohne zusätzliche Bibliotheken aufgebaut werden. Polymer und ReactJS sind eher Bibliotheken und keine kompletten Web Frameworks, da sie nicht so viele integrierte Funktionen anbieten. Der Fokus bei Polymer liegt auf den Web Components als reine wiederverwendbare Komponenten auf der Repräsentationsebene. Es stellt auch eine sehr große Menge vordefinierter, fertiger Web Components zur Verfügung. Bei ReactJS sieht die Situation ähnlich aus. Das Ziel der Bibliothek ist es, die Performanz von Web-Anwendungen mit wenig Code zu verbessern und die Entwicklung lose gekoppelter Komponenten zu ermöglichen. Dafür ist es aber schwierig, eine Web-Anwendung komplett in ReactJS ohne externe Bibliotheken zu implementieren, da keine integrierten Mechanismen zur Anbindung von Web Services, Navigation und Datenmanipulation in der Bibliothek vorhanden sind.

Angular 2 unterstützt die drei Programmiersprachen JavaScript, TypeScript und Dart, was eine hohe Flexibilität bei der Entwicklung ermöglicht. Mit ReactJS kann JavaScript oder JSX (eine Erweiterung von JavaScript, die XML ähnelt) verwendet werden. Polymer basiert nur auf JavaScript.

Es gibt auch syntaktische Unterschiede bei der Implementierung von Web Components in den drei Frameworks. Bei Angular 2 werden die grafischen HTML-Elemente der Web Component durch die Argumente der @Component-Annotation der Klasse erzeugt, die Festlegung des Verhaltens und der Eigenschaften der Web Component erfolgt in der Klasse selbst. Bei komplexerer HTML-Struktur kann der HTML-Code in eine separate HTML-Datei ausgelagert werden. Bei ReactJS muss die Basisklasse Component erweitert werden, um eine neue Web Component zu erstellen. Die Festlegung der grafischen Elemente und der Eigenschaften der Web Component erfolgt in der Klasse, aber eine Auslagerung des Codes des HTML Templates ist nicht möglich. Bei Polymer muss für jede Web Component jeweils eine HTML-Datei angelegt werden. Diese enthält das HTML Template der Web Component und innerhalb des Script-Elements werden Eigenschaften, Metadaten und Verhalten definiert. Ein weiterer Unterschied ist, dass bei Angular 2 und Polymer Web Components ein eindeutiger HTML Tag definiert werden muss, durch den die Identifikation und die Einbindung der Web Component im HTML-Code erfolgt. In ReactJS ist das aufgrund der JSX-Syntax nicht notwendig. Überdies unterstützten Angular 2 und Polymer sowohl eine Ein-Weg-, als auch eine Zwei-Wege-Datenbindung, während bei ReactJS nur eine Ein-Weg-Datenbindung möglich ist. [Ba16]

Angular 2 besitzt integrierte Mechanismen zur Implementierung von Routing oder Navigation zwischen den Komponenten einer Web-Anwendung. Diese Funktionalität ist bei ReactJS in einer externen, speziell für ReactJS-Applikationen konzipierten Bibliothek react-router ausgelagert. In Polymer existieren keine integrierten Mechanismen, die das erlauben. [Ba16]

Ein weiterer sehr wichtiger Aspekt, in dem sich die drei Frameworks unterscheiden, ist Rendering und Change Detection. In ReactJS ermöglicht die JSX-Syntax den Aufbau des Web Component Templates als Kombination von anderen Web Components und HTML-Elementen in einem XML-ähnlichen Stil. Das JSX Template wird dann Teil des virtuellen DOM von ReactJS. Bei Rendering der Komponenten im Browser, wird zuerst eine in-memory oder virtuelle Repräsentation des DOM-Baums mit allen Komponenten erzeugt. Anschließend wird der echte DOM-Baum aufgebaut und die Komponenten visualisiert. Dies ermöglicht eine sehr effiziente Reaktion auf Änderungen auf der Benutzeroberfläche, da bei jeder Änderung einen neuen virtuellen DOM-Baum aufgebaut wird. Danach wird der virtuelle DOM-Baum mit dem echten DOM-Baum mithilfe eines sehr effizienten Algorithmus verglichen und nur die Teile des echten DOM-Baums, die unterschiedlich sind, werden aktualisiert. Das führt zu einer wesentlichen Verbesserung der Performanz und ist der größte Vorteil von ReactJS, da der Zugriff auf den echten DOM-Baum und die Suche in diesem sehr großen Baum extrem aufwändig sind. [Ba16]

Bei Angular 2 und Polymer funktionieren Rendering und Change Detection anders. Sie bauen keine virtuellen DOM-Bäume auf. Wenn ein Ereignis, das eine Änderung beschreibt, ausgelöst wird, wird der gesamte DOM-Baum durchgesucht und die Änderungen an geeigneten Stellen im Baum vorgenommen. [Ba16]

2.8 Web Workers

Web Workers bieten gute Möglichkeiten zur Verbesserung der Performanz, sowie zum Erreichen von Elastizität und Antwortbereitschaft auf der Clientseite einer Web-Anwendung durch Auslagern von (rechenintensiven) Operation in einen separaten Browser-Prozess, der im Hintergrund ausgeführt wird. Im Folgenden wird das Konzept von Web Workers erläutert und verschiedene Web Worker-Klassen vorgestellt.

[...]

Ende der Leseprobe aus 97 Seiten

Details

Titel
Entwurf und Umsetzung einer nachrichtenorientierten Software-Architektur am Beispiel eines SmartCampus-Dienstes
Hochschule
Karlsruher Institut für Technologie (KIT)
Note
1,3
Autor
Jahr
2016
Seiten
97
Katalognummer
V424116
ISBN (eBook)
9783668698086
ISBN (Buch)
9783668698093
Dateigröße
2909 KB
Sprache
Deutsch
Schlagworte
entwurf, umsetzung, software-architektur, beispiel, smartcampus-dienstes, nachrichtenorientierte architektur
Arbeit zitieren
M.Sc. Radoslav Yankov (Autor), 2016, Entwurf und Umsetzung einer nachrichtenorientierten Software-Architektur am Beispiel eines SmartCampus-Dienstes, München, GRIN Verlag, https://www.grin.com/document/424116

Kommentare

  • Noch keine Kommentare.
Im eBook lesen
Titel: Entwurf und Umsetzung einer nachrichtenorientierten Software-Architektur am Beispiel eines SmartCampus-Dienstes


Ihre Arbeit hochladen

Ihre Hausarbeit / Abschlussarbeit:

- Publikation als eBook und Buch
- Hohes Honorar auf die Verkäufe
- Für Sie komplett kostenlos – mit ISBN
- Es dauert nur 5 Minuten
- Jede Arbeit findet Leser

Kostenlos Autor werden