Event-driven Microservices & Event Processing

2 Kommentare

Auf dem Weg von einem Monolithen oder einer grünen Wiese zu einer Landschaft von Microservices sind viele Pfade zu beschreiten und Design-Entscheidungen zu treffen. Neben dem Aufbau fachlich sinnvoll abgegrenzter Serviceeinheiten gilt ein Augenmerk der Kommunikation der Services untereinander. Schließlich soll verhindert werden, dass am Ende nicht doch wieder ein Weg eingeschlagen wird, der zu einem Monolithen aus Services führt, der dann verteilt und fest verdrahtet im Rechenzentrum ruht. Womit das eigentliche Ziel, die lose Kopplung der Services zu erreichen, konterkariert wird.

Unter Umständen ungünstige Entkopplung von Komponenten einer Applikation

Unter Umständen ungünstige Entkopplung von Komponenten einer Applikation

Eine Variante der fest verdrahteten und komplexen Kommunikation zwischen den Services zu begegnen liegt im Einsatz eines Mediators und der asynchronen Kommunikation zwischen den Services. Im Kontext einer Systemintegration kommt dabei als Mediator in der Regel ein Message Broker zum Einsatz. Das Request/Response Pattern, wie es bei gängigen Ansätzen (beispielsweise RESTful Services) Anwendung findet, wird ersetzt durch eine Nachrichten-basierte Kommunikation. Die Services übergeben einem Broker ihre Nachrichten und der Broker stellt den Empfängern die Nachrichten für eine definierte Zeit zur Verfügung. Wann und vom wem die Nachricht verarbeitet wird ist für den Nachrichtensender dabei völlig intransparent. Ferner erwartet der Sender auch keine Antwort, wie es bei einem synchronen Request/Response Verfahren der Fall wäre [1].

Event-Channel

Diese asynchrone Kommunikation ist die Basis einer Event-driven Architecture (EDA) und wird durch einen Message Broker und das Publish/Subscribe Pattern als Event-Channel realisiert.

Event-Channel

Event-Channel zur Entkopplung der Komponenten und deren direkten Kommunikation miteinander – nicht zu verwechseln mit einem ESB

Der Publish/Subscribe-Ansatz ermöglicht darüberhinaus, dass eine Nachricht nicht nur von einem Service oder sonstigen Komponente gelesen wird, sondern von mehreren Konsumenten.

Events vs. Commands

Die übertragenen Nachrichten respektive Events enthalten keine Anweisungen bzw. explizite Kommandos wie es beispielsweise beim CRUD-Ansatz und dem direkten Ausführen von Aktionen der Fall wäre. Vielmehr beschreibt ein Event was geschehen ist.

An event is a notable thing that happens inside or outside your business. [2]

So wird in einem E-Commerce Shop das Event Customer Tom did a purchase.
an einen Message Broker übermittelt, aber nicht eine Kette von Requests an RESTful Services abgesetzt, die Aktionen wie:

  1. Create a Cart Object for Customer Tom
  2. Create an Address Object for Customer Tom
  3. et cetera

realisieren.
Darüberhinaus sind folgende Aspekte und Bedingungen zu beachten:

  • Ein Event enthält all die relevanten Daten, die von möglichen Kandidaten von Konsumenten benötigt werden um das Event sinnvoll verarbeiten zu können. So benötig ein Invoice-Service, der Toms Adresse auf die Rechnung schreiben muss, die Daten der Adresse.
  • Ein Konsument muß die Daten die er benötigt, selber vorhalten und aktualisieren. Das heist, der Invoice-Service wird Toms Rechnungsadresse bei einem Address-Service nicht explizit erfragen müssen – falls ein dedizierter Address-Service in dem System überhaupt existiert.
  • Die Konsumenten müssen Idempotenz gewährleisten, damit, falls ein Event mehrfach gelesen wird, es nicht zweimal berücksichtigt wird.
  • Die Daten in einem Event sind immutable – sie werden nicht geändert. Falls sich der Status der Daten ändert, ist ein neues Event zu erzeugen, das den neuen Datensatz inklusive der Änderungen beinhaltet.

Mindshift

Die Einführung einer Architektur basierend auf Microservices erfordert schon ein gewisses Umdenken bei der Frage, wie welche Probleme zu lösen sind. Beispielsweise ist vom kanonischen Datenmodell Abstand zu nehmen, Bounded Contexts sind bei der Modellierung zu bevorzugen und Datenduplizierung kein No-go mehr.
Bis zur Etablierung einer EDA sind, wie oben schon für Events beschrieben, eine Reihe Paradigmen und Gewohnheiten aufzugeben, mit ebenso großem Einfluß auf die Entwicklung. Insbesondere existiert:

  • keine direkte Kommunikation – es wird nur durch Events kommuniziert was geschah. Der Sender weiß nicht, wer sein Event empfängt und wie der Empfänger den Inhalt nutzt.
  • keine Interaktionen basierend auf einem Callstack – es gibt keine zentrale Instanz, die durch synchrone Aufrufe von Subroutinen Prozesse Schritt für Schritt abarbeitet und den aktuellen Status in einem Prozess vorhält [3]
  • keine Service-Orchestration, sie wird abgelöst durch eine Service-Choreographie

Allerdings ist eine EDA natürlich auch nur wieder eine weitere Möglichkeit Softwaresysteme aufzubauen und nicht der Weisheit letzter Schluß um jedwede Softwarelösung mit Hilfe dieses Architekturansatzes zu realisieren. Die finale Architektur wird eher polyglotter Natur sein und die EDA zum Beispiel nur einen Blick in die Systemlandschaft und Aktivitäten zur Laufzeit ermöglichen.

Complex Event Processing & Event Stream Processing

Liegt der Fokus beim Aufbau eine Systems aus Microservices zunächst nur darauf, die lose Kopplung mit Hilfe einer EDA zu arrangieren, geht allerdings ein nicht unwesentlicher Aspekt des EDA-Ansatzes unter – Complex Event Processing (CEP).

Complex event processing is a new technology for extracting information from message-based systems. – David Luckham and Brian Frasca, 1998

Die Möglichkeit, Events auf einer höheren Abstraktionsstufe ableiten zu können, sie regelbasiert zu verarbeiten oder Eventströme in Echtzeit zu monitoren, sind zentrale Merkmale die diesen Architekturansatz charakterisieren und antreiben.

Eigenschaft einer Event-driven Architecture mit Complex Event Processing [4]
Eigenschaft EDA mit CEP
Perspektive Echtzeitfähigkeit
Ereignisverarbeitung einfache und komplexe Ereignismuster (event pattern matching), unter Einbeziehung von Kontextinformationen (content enrichment)
Abstraktionsgrad Abstraktion von einfachen zu fachlich höherwertigen Ereignissen ergibt Abstraktionshierarchie
Mengengerüst Verarbeitung von Massenereignisdaten aus mehreren Ereignisströmen
Wissensrepräsentation explizit in CEP-Komponente; Wissen über Ereignisverarbeitung deklarativ in Form von Regeln formuliert

Der Begriff Complex Event Processing wurde dabei schon in den 1990er geprägt, wobei der heutzutage gern ins Spiel gebrachte Begriff, Event Stream Processing erst später aufkam und einen etwas anderen Fokus hat:

Event stream processing is focused more on high-speed querying of data in streams of events and applying mathematical algorithms to the event data. Some of the first commercial applications were to stock-market feeds in financial systems and algorithmic trading. CEP is focused more on extracting information from clouds of events created in enterprise IT and business systems. CEP includes event data analysis, but places emphasis on patterns of events, and abstracting and simplifying information in the patterns. The idea is to support as wide an area of enterprise management decision making as possible. The first commercial applications were in the Business Activity Monitoring, for example monitoring conformance to service level agreements. [5]

Im folgenden soll Complex Event Processing den Ansatz des Event Stream Processing mit umfassen.

Eventstruktur

Um CEP zu ermöglichen, ist allerdings die Definition und Einführung systemweit gültiger Spezifikationen nötig. Zum Beispiel wird, wenn die asynchrone Kommunikation erst mal etabliert, Kommandos eliminiert und Nachrichten eingeführt sind, im nächsten Schritt eine zentrale Eventstruktur sowie ein Eventmodel zum Einsatz kommen müssen. Andernfalls ist eine regelbasierte Verarbeitung von Events nur umständlich zu erreichen.
So sind zum Beispiel neben der eigentlichen Payload domänenunabhängige Meta-Daten wie:

  • eine Event-Id – gewährleistet die eindeutige Unterscheidung von Events,
  • ein Event-Type – spezifziert den fachlichen Inhalt/Payload des Events,
  • ein Timestamp – Zeitpunkt des Auftretens des Events,
  • die Source – Komponente die das Event erzeugt hat

unabdingbar, um ein Event für die Weiterverarbeitung einordnen zu können.
Diese zentrale Struktur schränkt die gerade eingeführte Flexibilität bei der Interfacegestaltung der einzelnen Microservices aber schon wieder ein. Es ist daher abzuwägen inwieweit es sinnvoll ist, sich auf ein zentrales Konzept und Strukturen zur Verarbeitung von Events einzulassen – insbesondere wenn die „Autonomie“ der Services als ein hohes Gut betrachtet wird. Im Rahmen einer Makroarchitektur für ein System sind solche Strukturen aber durchaus diskutierbar. Insbesondere verlassen sich die Konsumenten neben den Meta-Daten schon auf eine feste Struktur; die der eigentlichen Payload. Durch die Struktur der Payload besteht weiterhin eine Kopplung zwischen einem Sender und den Empfängern seiner Nachricht.

CEP-Lösungen

Eine Übersicht über den derzeitigen Markt an CEP-Lösungen würde den Rahmen dieses Artikels sprengen, aber eine, insbesondere auch historische Übersicht, befindet sich auf complexevents.com [6].
Die Einführung einer CEP-Enterpriselösung im großen Stil ist mit Aufwänden verbunden, die fachlich wie technisch zu rechtfertigen sind, und den Schritt hin zur EDA mit CEP und deren Vorteilen lohnen müssen.
Das heisst es wird nicht immer sinnvoll sein, auf eine Enterpriselösung komplett umzustellen, insbesondere wenn der fachliche Kontext es gar nicht hergibt.

Lightweight CEP – Beispiel

Stehen die Events in einem Event-Channel zur Verfügung und besitzen diese die oben genannten Meta-Daten, ist der nächste Schritt, mit „komplexen“ Events zu arbeiten, nicht mehr weit.
Der Aufbau einer leichtgewichtigen CEP-Lösung lässt sich dabei reduzieren auf die Komponenten [7]:

  • Event processing agent (EPA) (event processing component, event mediator): A software module that processes events.
  • Event processing network (EPN): A set of event processing agents (EPAs) and a set of event channels connecting them.
  • Event processing language (EPL): A high-level computer language for defining the behavior of event processing agents.
Event Processing Agent and Network

Event Processing Agents verarbeiten fachlich klar definierte Teilaufgaben und sind als ein Event Processing Network strukturierbar

Das folgende Beispiel basiert auf dem Open-Source-Projekte Esper [8] und Apache Camel [9]. Esper stellt eine Processing Engine und eine Event Processing Language (EPL) zur Verfügung, um Events auf Event-Strömen beispielsweise filtern, aggregieren oder joinen zu können. Apache Camels Esper-Komponente ermöglicht eine standardisierte Integration der Esper Processing Engine um Events aus verschiedenen Quellen lesen und schreiben zu können. Ein Event Processing Agent lässt sich somit schon recht einfach realisieren und beispielsweise als Spring-Boot-Applikation deployen.
Der folgende Sourcecodeausschnitt beschreibt eine Camel Route, die Events des Typs CartCreatedEvent beständig aus einem Eventstream ausliest und in einem Zeitfenster von fünf Sekunden auswertet. Falls der mittlere Umsatz während der fünf Sekunden geringer als 700 ist, wird ein neues Event LowConversion erzeugt und an den Event-Channel gesandt.

from("esper://esper?eql=insert into de.codecentric.LowConversionEvent(avgTotalAmount) 
       select 
          avg(totalAmount) as avgTotalAmount 
       from 
          de.codecentric.CartCreatedEvent.win:time_batch(5 sec)
       having 
          avg(totalAmount) < 700
    ")
.to("seda:eventChannel");

Die SQL-ähnlichen Queries sind dabei statisch und nur die Daten im Stream ändern sich. Das Vorgehen ist quasi umgekehrt zu einem Datenverarbeitungsansatz basierend auf einem RDBMS und SQL, bei dem die Queries meist recht variabel und die Daten eher statisch sind.
Der Event-Channel ist hier realisiert als ein Topic eines Kafka-Brokers. Eine Camel-Route ließt die Events aus dem Topic und stellt sie der Esper Processing Engine als Objekte zur Verfügung (hier nicht dargestellt). Der Sourcecode sowie weitere Beispiele, inklusive Testdatenerzeugung und Kafka-Server-Einrichtung sind im GitHub Repository [10] verfügbar. Der Code enthält dabei natürlich nur die für die Beispiele relevanten Teile und Attribute und ist für einen produktiven Einsatz nicht ausreichend.

Business Monitoring

Sind die Events erst einmal im Event-Channel, lassen sich diese auch nach verschiedenen Kriterien monitoren und visualisieren – zum Beispiel mit dem Elastic-Stack, ehemals ELK Stack genannt [11]. Dazu kann die Logstash-Komponente des Stacks die Events aus dem Kafka-Topic auslesen und dem Elastic Server zur Verfügung stellen. Die Events lassen sich dann nach verschiedenen Kriterien auswerten und mit Hilfe der Komponente Kibana visualisieren.
Im folgenden Screenshot stellt das Tortendiagramm die Häufigkeit der einzelnen Events in Relation. Das Balkendiagramm zeigt einen Durchschnittswert über die avgTotalAmount der LowConversion Events und der Graph beschreibt einen Mittelwert der Umsätze der letzten Einkäufe. Automatische Aktionen zum Beispiel beim Über- oder Unterschreiten von bestimmten Grenzwerten sind dabei ebenso schon mit Esper Event-Listener und den Camel Routen realisierbar.

Kibana Screenshot

Visualisierung von Events mit hilfe des ELK Stacks

Performance

Um der Herausforderung der möglichen schieren Masse an auftretenden Events und Performanceengpässen Herr zu werden, spielt die fachliche Aufbereitung eine nicht unwesentliche Rolle.
Durch Event Processing Networks lassen sich komplexe fachliche Aufgaben strukturieren und in kleinere, fachlich klar definierte Teilaufgaben zerlegen. Diese Teilaufgaben sind dann durch leichtgewichtige skalierbare Agenten realisierbar. Ferner läßt sich durch das Filtern von Events und einer geschickten Strukturierung die Masse der zu verarbeitenden Events Schritt für Schritt reduzieren – was der Performance zuträglich sein wird. Darüberhinaus existieren mittlerweile eine ganze Reihe von Lösungen auch im Open-Source-Bereich, die gerade den Performance- und High-Availability-Aspekt adressieren [6] – siehe Distributed Stream Computing Platform (DSCP).

Geht’s noch komplexer?

Der Mitte der 90er Jahre aufgekommene EDA-Ansatz, damals in Kombination mit einer Service orientierten Architektur, kann als Kommunikationsbasis für Microservices zu einer weiteren Entkopplung der Services führen und Stabilität ins System bringen. Complex Event Processing ermöglicht darüberhinaus die Informationsverarbeitung auf neue Füße zu stellen und einen Einblick ins System zur Laufzeit zu geben. Das Design der Systeme wird aber unter Umständen komplexer, da ein kontrollierbarer Callstack nicht existiert und die Zusammenarbeit der Services nicht mehr orchestrierbar ist. Und somit mehr Aufwand entsteht den aktuellen Status eines inhärenten Prozessablaufs zu ermitteln.

Referenzen

[1] EIP – Messaging
[2] Event-Driven Architecture
Overview – Event-Driven SOA Is Just Part of the EDA Story

[3] Programming Without a Call Stack – Event-driven Architectures
[4] Event-Driven Architecture: Softwarearchitektur für ereignisgesteuerte Geschäftsprozesse, Xpert.press, ISBN 978-3-642-02439-9
[5] Real Time Intelligence & Complex Event Processing
[6] CEP Tool Market
[7] Event Processing for Business: Organizing the Real-Time Enterprise, John Wiley & Sons, ISBN 978-0470534854
[8] EsperTech
[9] Apache Camel
[10] Event Processing Sample
[11] ELK Stack

Berthold Schulte

Berthold ist Informatiker mit langjähriger Erfahrung in der Konzeption und Realisierung von Softwarelösungen verschiedenster Komplexität und Größenordnung. Seit dem Jahr 2000 reist er durch die Java-Welt mit Aufenthalt in unterschiedlichen Branchen. Die Anforderungsanalyse und Softwarearchitektur prägten dabei seinen Alltag. Sein Fokus liegt derzeit auf Event-getriebenen Architekturansätzen im Rahmen von Big-Data-Lösungen.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Artikel von Berthold Schulte

Weitere Inhalte zu Architektur

Kommentare

  • August 17, 2016 von Benjamin Carl

    Hi Berthold,

    toller Artikel und vor allem sehr gut auf den Punkt gebracht und sehr gute Querverweise eingebunden! Mir gefällt der gesamte Ansatz. Ich selbst war Teil eines zwei-phasigen Umbaus von Monolith zu Microservice-Architektur und anschließendem (erweiterten) Ausbaus auf Event-Driven Messaging (eigene Implementierung auf Symfony 2-/Silex-Basis) in einem Kölner Automobil Start-Up und kann aus der Praxis berichten, dass dies eine sehr schöne und vor allem sehr gut pfleg- und wartbare Architektur ergibt.

    Es würde den Rahmen sprengen all die weiteren Vorteile auch im Bezug auf Personal/Ressourcen zu erwähnen. Ein wichtiger Punkt aus meiner Sicht war der, das diese Architektur durch das Team (oder Teams) sehr gut bedient werden kann. Woraus sich wieder eine Reihe weiterer Vorteile ergeben.

    Leider gibt es jedoch immer noch Unternehmen, die einen gänzlich anderen Ansatz wählen und dazu auch noch „beratungsresistent“ sind.

    Freue mich schon auf weitere Artikel von euch (dir).

    • Berthold Schulte

      August 17, 2016 von Berthold Schulte

      Hallo Benjamin,

      Vielen Dank für Dein Kommentar.
      Ja, in der Tat, es bleibt spannend zu sehen inwieweit sich solche EDA Ansätze etablieren können. Wenn sich dazu noch ein positiver Einfluß auf die Teams ergibt, um so besser.

      Gruß

      Berthold

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *