Aus Linux-Magazin 07/2023

Cadence – das Workflow-Kubernetes

© Dmytro Sidelnikov / 123RF.com

Cadence verspricht, sichere, skalierbare und hochverfügbare Workflows zu orchestrieren. Das Ziel – vereinfachte Entwicklung und Betrieb komplexer Abläufe – ähnelt dem vieler Low-Code-Plattformen. Allerdings gibt es hier statt wenig Code ausschließlich Code, der aber magische Kräfte entfalten kann.

Wenn Literaturwissenschaftler oder Musiker über eine Kadenz reden, dann sprechen sie über die Betonung der letzten Silben innerhalb eines Verses beziehungsweise über eine Akkordfolge. In beiden Fällen steht die Kadenz für eine harmonische Wendung. Diese Eigenschaft, die Wirkung der Harmonie, wünschen sich Unternehmen auch für die Modellierung, den Betrieb und das Management ihrer Geschäftsprozesse. Das Ziel ist aber nicht leicht zu erreichen, gerade im Kontext der immer häufiger anzutreffenden Microservice-Architekturen. Zudem werden auch die Geschäftsprozesse selbst immer komplexer, was Unternehmen vor große Herausforderungen stellt. Um diese Art von Aufgaben auf stimmige Art leicht beherrschbar zu machen, hat das Fahrdienstleistungsunternehmen Uber eine fehlertolerante und zustandsbehaftete Workflow-Engine mit dem passenden Namen Cadence [1] entwickelt.

Das 2017 unter der MIT-Lizenz veröffentlichte Tool [2] ordnet sich in eine Reihe hochskalierbarer Open-Source-Technologien ein, die in den letzten Jahren die IT-Branche eroberten. Eines der bekanntesten Beispiele ist Kubernetes, der Industriestandard für das Container-Management. Mit ihm teilt sich Cadence einige grundlegende Aspekte. Allerdings geht es bei der Lösung von Uber nicht um Container, sondern eben um die Orchestrierung von Geschäftsprozessen.

Workflows

Im Geschäftsalltag gibt es sehr viele Workloads. Ein typisches Beispiel aus dem E-Commerce-Bereich ist der Bestellprozess. Oberflächlich betrachtet geht es darum, dass ein Artikel vom Anbieter zum Kunden gelangt und dafür Geld den Besitzer wechselt. Dieser Ablauf scheint auf den ersten Blick ziemlich geradlinig. Doch es erfordert viele Teilschritte, um vom Start- zum Endpunkt der erfolgreichen Transaktion zu gelangen. Sie gehen teils über einen einzelnen Microservice oder eine einzelne Anwendung hinaus. Nutzer, die das mit Cadence modellieren, profitieren von zwei Besonderheiten.

Die erste ist, dass Workflows in Cadence ihren aktuellen Zustand behalten, wenn sie während des Prozessablaufs auf ein Problem stoßen und nicht wie erwartet abgearbeitet werden können. Die zweite ist, dass Nutzer Workflows nicht über eine grafische Benutzerschnittstelle definieren, sondern durch Code. Die Workflow Engine richtet sich daher in erster Linie an Entwickler und erleichtert ihnen die Arbeit. Für die Implementierung der Workflow-Logik stehen offiziell Client-Libraries für Go und Java zur Verfügung. Aus der Community kommen weitere für Ruby und Python hinzu.

Vorteil Cadence

Auf ihrem Weg vom Start zum vorbestimmten Ziel durchlaufen Workflows verschiedene Stadien und Zustände und absolvieren viele Zwischenschritte (Activities). Genaue Informationen, wann und wie ein Workflow oder eine Activity abzuarbeiten ist und welchen Kontext es gibt, liefern Workflow Tasks (auch Decision Tasks) und Activity Tasks. Dazu später mehr.

Viele Activities sind redundant, dasselbe gilt für die meisten Workflows. An dieser Stelle hilft das fehlertolerante und zustandsbehaftete Programmiermodell von Cadence. In einem Bestellprozess im E-Commerce kommt es beispielsweise im Normalfall an irgendeinem Punkt zur Bezahlung. Während dieses Vorgangs findet eine Kommunikation zwischen dem Webshop und der Bezahl-App über deren API statt. Kommt es nicht direkt zu einer Antwort – etwa, weil der Kunde sich erst einmal einloggen und bestimmte Einstellungen vornehmen muss – behält der Workflow in Cadence seinen Zustand bei, bis dieser Schritt erfolgreich abgeschlossen ist. Danach geht es mit dem nächsten Vorgang weiter.

In klassischen Systemen würde im obigen Beispiel ein großes Problem entstehen, denn die ausbleibende Antwort würde möglicherweise zu einem Abbruch der Transaktion führen. Infolgedessen müsste der Kunde eventuell den gesamten Einkauf von vorn beginnen. Freilich können Entwickler mit entsprechenden Anwendungsfunktionen einen Abbruch verhindern, allerdings produzieren sie dabei Unmengen an Code. Zudem verschlingt dieser Programmieraufwand kostbare Ressourcen etwa an Arbeitszeit, die Unternehmen besser verwenden können. Cadence dagegen vermag sogar essenzielle Nodes für Teile eines Workflows automatisiert hochzufahren oder neu zu starten, ohne dass der aktuelle Zustand verloren geht.

Workflows definieren

Das Programmiermodell von Cadence erscheint auf den ersten Blick etwas kompliziert. Die Dokumentation ist ebenfalls an manchen Stellen verbesserungswürdig. Für die folgenden Erläuterungen dient die Java-Client-Library als Grundlage. Prinzipiell funktioniert Cadence aber auch mit Go, Python oder Ruby auf ähnliche Art und Weise.

Der erste Schritt, um einen Workflow in Java zu implementieren, besteht im Bau eines Interfaces. Es enthält zunächst einmal den Startpunkt (Entry Point) des Workflows, wobei die Logik gebietet, dass es nur einen Startpunkt gibt. Um ihn festzulegen, definiert der Entwickler eine Workflow-Methode. Laut allgemeiner Konvention nennt er sie »@WorkflowMethod«. Für den Start genügt es, nur den Namen der Methode und eine Signatur (beispielsweise »startWorkflow«) festzulegen. Sie könnte auch weitere Parameter enthalten, aber zunächst genügt es, ihr ein generisches Argument mitzugeben und später weitere Properties hinzuzufügen.

Neben der »@WorkflowMethod« umfasst das Interface für gewöhnlich weitere Methoden, die der Workflow braucht. Will man etwa abfragen können, in welchem Zustand sich ein aktiver Workflow befindet oder an welcher Stelle er gerade steht, bietet sich eine Query-Methode an. Analog zur »@WorkflowMethod« heißt sie in der Regel »@QueryMethod«. Gehört zum Workflow beispielsweise der Download einer großen Datei von einem S3-Server, könnte der Entwickler eine Abfrage implementieren, die zurückmeldet, wie viel Prozent der Datei bereits heruntergeladen wurden. Da es manchmal nötig ist, Prozesse von außen anzusteuern, gibt es die Signal-Methode. Sie heißt »@SignalMethod« und erlaubt es – um beim Beispiel des Downloads zu bleiben – den Datentransfer abzubrechen oder zu pausieren, sobald ein bestimmtes Ereignis eintritt

Implementierung in Java

Für die Implementierung des Interfaces müssen Entwickler eine Klasse erstellen. Sie überschreibt via »@Override« alle Methoden im Interface und enthält den sogenannten Custom Code, also die Business-Logik. Das kann zum Beispiel die Kommunikation mit einer externen Schnittstelle sein, wie im obigen Beispiel zwischen dem Payment Workflow und der Bezahl-App über ein bestimmtes API. Das Überschreiben ist deswegen so wichtig, weil die individuelle Business-Logik unter Umständen in einem Fehler enden kann. Außerdem ermöglicht Cadence es Entwicklern auf diese Weise, dasselbe Interface wiederzuverwenden.

Cadence besteht aus verschiedenen internen wie externen Diensten, die sich zum Cadence-Service vereinen. Zunächst ist jedoch erst einmal wichtig, dass dieser Service die Implementierung an einen Worker-Service weiterleitet. Die Client-seitigen Dienste sind zustandslos (stateless) und führen den Code schließlich aus. An dieser Stelle ähnelt Cadence Kubernetes: Stürzt ein Container ab, startet die Orchestrierungsplattform ihn einfach neu. Das funktioniert, weil die relevanten Informationen zentral gespeichert sind. Bei Cadence liegen diese Events in sogenannten Task-Listen vor: Die Workflow-Engine speichert alle Tasks sämtlicher Implementierungen in zwei Listen, jeweils einer für Workflow- und für Activity-Tasks.

Stürzt also ein Worker-Service ab und wird durch einen neuen ersetzt, spricht er den Cadence-Service über das sogenannte Frontend an. Im Kontext von Cadence meint dieser Begriff das API-Gateway, über das die Kommunikation mit der Außenwelt stattfindet. Der Cadence-Service initiiert ein Event-Sourcing, sammelt alle ausgeführten Tasks und gibt die Liste bereits ausgeführter Tasks an den neuen Worker-Service weiter, um ihn wieder auf Stand zu bringen und den alten zu ersetzen. Wer möchte, kann die Worker-Dienste übrigens auch in Container verpacken.

Als Activities bezeichnet man, wie bereits erwähnt, die einzelnen Schritte in einem Workflow, also das, was zwischen seinen Zuständen passiert. Sie funktionieren auf dieselbe Weise: Auch für sie erstellen Entwickler ein Interface, das Methoden enthält. Die Standardmethode heißt »@ActivityMethod«.

Architekturüberblick

Wie bereits erwähnt, beinhaltet die Workflow-Engine Cadence eine Reihe von internen wie externen Komponenten, die zusammen den Cadence-Service bilden. Außerhalb des Cadence-Service selbst gibt es Client-seitige Dienste, mit denen Entwickler ihren individuellen Code (etwa die Business-Logik) implementieren.

Dazu gehören zunächst einmal externe Clients, also Anwendungen, die mit den Cadence-Workflows interagieren. Die Frontend-Applikation eines Webshops könnte zum Beispiel einen Workflow für die Verarbeitung einer Bestellung anstoßen. Die bereits bekannten Workflow- und Activity-Worker sind Dienste, mit denen Entwickler die Business-Logik für eine bestimmte Funktion (also einen Workflow oder eine Activity) implementieren. Sie sind stateless und lassen sich jederzeit ersetzen.

Activity-Worker können zudem sogenannte Business-Services aufrufen – also Microservices, APIs von Drittanbietern, Messaging-Systeme oder vergleichbare Anwendungen. Cadence selbst stellt ebenfalls zwei Client-seitige Dienste bereit: ein Command Line Interface (Cadence CLI) und eine Webapplikation (Cadence Web, Abbildung 1), über die Nutzer den Status aktiver Workflows inspizieren und sie beenden können.

Abbildung 1: Eine Webapplikation dient der Steuerung und Überwachung der Workflows.

Abbildung 1: Eine Webapplikation dient der Steuerung und Überwachung der Workflows.

Zwischen diesen Client-seitigen Services und dem Cadence-Dienst sitzt ein Load Balancer, der die Lastverteilung übernimmt und die hohe Verfügbarkeit für Frontend-Services gewährleistet (Abbildung 2). Je nachdem, in welchem Umfeld Cadence läuft, stellt ihn entweder Kubernetes oder der Cloud-Provider bereit.

Abbildung 2: Dieses Diagramm gibt eine Übersicht über die Cadence-Architektur.

Abbildung 2: Dieses Diagramm gibt eine Übersicht über die Cadence-Architektur.

Die externen Clients verbinden sich mit Cadence über das API, das der Front-End-Service bereitstellt. Er stellt ein klassisches API-Gateway dar. Der History-Service speichert eine Ausführungshistorie für jeden absolvierten Schritt eines Workflows und einer Activity. Wichtig ist, dass er nicht selbst die Workflow-Logik ausführt. Er stellt lediglich sicher, dass jeder Schritt zuverlässig abgearbeitet wird.

Der Matching-Service arbeitet eng mit dem History-Service zusammen: Wenn Letzterer erkennt, dass es einen Task auszuführen gilt, übergibt er ihn an den Matching-Service. Dessen Aufgabe ist es dann, einen Workflow- oder Activity-Worker zu finden, der den Task ausführen kann. Da einige Zusatzfunktionen von Cadence (etwa die Archivierung) selbst als Cadence-Workflows implementiert sind, benötigt die Workflow Engine einen eigenen Worker-Prozess. Er nennt sich Internal Worker.

Zu guter Letzt gibt es einige externe, für die Funktionalität von Cadence relevante Dienste. Dazu gehört unter anderem eine Datenbank, die die Persistenz interner Daten wie der Workflow-Historie gewährleistet. Cadence unterstützt nativ unter anderem Apache Cassandra, PostgreSQL und MySQL. Unternehmen, die aktive oder bereits beendete Workflows nach bestimmten Kriterien durchsuchen möchten, müssen Cadence dafür einen Apache-Kafka- sowie einen OpenSearch-Cluster bereitstellen. Diese Abhängigkeiten prädestinieren die Workflow-Engine für den Einsatz im Umfeld einer Managed Platform, die die Verwaltung dieses Toolsets vereinfacht.

Nächste Schritte

Seit Uber der Öffentlichkeit Cadence unter der MIT-Lizenz zugänglich gemacht hat, floss bereits viel Herzblut unabhängiger Entwickler und vieler Unternehmen in die Workflow Engine. Trotzdem steht sie noch ganz am Beginn ihrer Reise. Glücklicherweise ist die Innovationskraft der Open-Source-Gemeinde enorm, weshalb Cadence das Potenzial hat, die IT-Branche in Zukunft nachhaltig zu prägen.

Mittlerweile gibt es sogar Gerüchte, dass Cadence Teil der Cloud Native Computing Foundation (CNCF) werden könnte. Dieser Schritt würde dem Tool sicher noch größere Popularität bescheren, als es bis dato als Uber-Projekt erhalten hat. (jcb/jlu)

Der Autor

Merlin Walter ist Staff Sales Engineer EMEA bei Instaclustr by NetApp.

Infos

  1. Cadence-Webseite: https://cadenceworkflow.io
  2. Cadence auf Github: https://github.com/uber/cadence
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben