© Manu Padilla/Shutterstock.com
Anwendungsentwicklung mit dem Axon Stack

Event-basiert und evolvierbar


Obgleich das Zielbild sowohl ein Monolith als auch eine Microservices-Architektur sein kann – das Axon Framework offeriert einen leichtgewichtigen Ansatz zur Implementierung Event-basierter Anwendungen. Dabei stützt sich das Framework auf gängige Muster aus dem Domain-driven Design (DDD) [1] und begünstigt die Umsetzung einer Anwendung nach dem Architekturprinzip Command Query Responsibility Segregation (CQRS) [2] und der Persistenzstrategie Event Sourcing [3]. Durch diese Flexibilität und die Tatsache, dass das Axon Framework bestens mit dem Spring Framework integriert ist und damit ein quasistandardisiertes Programmiermodell unterstützt, ist es für den modernen Java-Entwickler einen Blick wert.

Das Axon Framework [4] unterstützt die Modellierung nach den Konzepten des Domain-driven Design und arbeitet konsequent nachrichtenorientiert. Ob man über diese Nachrichten Domänen-Events zwischen Komponenten austauscht oder als Grundlage der Persistenzstrategie begreift, ist dem Entwickler überlassen. Durch den Fokus auf Richtlinien des DDD ist der Entwickler an einen modularen, fachlichen Schnitt in der Anwendung gehalten. Das erlaubt es, zunächst einfach und monolithisch zu starten und sobald die Notwendigkeit gegeben ist, die Architektur in Richtung einer Microservices-Landschaft zu evolvieren (Abb. 1). Genauer gesagt kann eine Axon-gestützte Anwendung als Monolith beginnen, da durch die Event-basierte Kommunikation und die fachliche Modularität, die man durch DDD gewinnt, der Grundstein für eine Migration hin zu einer Microservices-Architektur gelegt ist.

guenther_axon_1.tif_fmt1.jpgAbb. 1: Evolvierfähigkeit einer Axon-gestützten Anwendung

Es hindert aber auch nicht daran, direkt mit Microservices zu starten. Um einen angemessenen fachlichen Schnitt für die Aufspaltung in unterschiedliche Services zu finden, macht man sich das Konzept des Bounded Context aus dem DDD zu Nutzen. Zur Datenintegration kommunizieren Microservices über definierte Schnittstellen miteinander. Ein Kernkonzept des Axon Frameworks ist es, Zustandsveränderungen an einem Aggregat durch die Publikation eines dedizierten Events anderen Microservices gegenüber zu signalisieren. Events sind damit zentraler Bestandteil der Schnittstelle. Event-konsumierende Anwendungen entscheiden selbst, wie sie diese Events interpretieren. Das macht die Umsetzung von CQRS als Architekturmuster einfach: Über eine dedizierte Schnittstelle führt man Zustandsveränderungen in das System ein und publiziert die entsprechenden Events, die eine Event-konsumierende Anwendung zu individuellen Lesemodellen verarbeitet. Diese Projektionen folgen der Philosophie, dass es nicht die eine wahre Repräsentationsform unserer Daten gibt, sondern je nach Anwendungsfall unterschiedliche Darstellungsarten geeignet sind. In Kombination mit Event Sourcing erhält man über den Event Store eine Single Source of Truth, durch die man diese Lesemodelle jederzeit neu aufbauen kann (Abb. 2).

Grundsätzlich lässt sich diese Applikationsarchitektur mit klassischen Mitteln realisieren. Eine korrekte und zuverlässige Implementierung von CQRS nebst Event Sourcing in einem verteilten System birgt jedoch Herausforderungen an das Event Routing und demzufolge auch an die Datenkonsistenz. Der Axon Stack bietet hierfür praxiserprobte Lösungen an. Das Axon Framework stellt als Teil dieses Stacks die programmatischen Primitive bereit. Es unterteilt sich in zwei funktionale Bestandteile:

Das Domain Model bildet den Kern des Axon Frameworks und stützt sich auf die Konzepte des Domain-driven Designs als fundamentalen Baustein zur Entwicklung von Axon-basierten Anwendungen.

Das Dispatch Model repräsentiert die logische Sicht auf die Infrastruktur und unterstützt die wesentlichen Operationen, an denen ein Bounded Context partizipiert. Axon unterscheidet zwischen drei Nachrichtentypen, die es über korrespondierende Busse verteilt:

  1. Commands: Commands repräsentieren gewünschte Zustandsveränderungen an einem Aggregat. Der Command Bus leitet ein Command stets zu einem dedizierten Handler, der sich für dessen Bearbeitung verantwortlich zeigt. Laufen mehrere Anwendungsinstanzen parallel, die einen solchen Command Handler tragen, sorgt konsistentes Hashing über dem Aggregat-ID-Raum für die Zustellung an die zuständige Anwendungsinstanz.

  2. Events: Publizierte Events signalisieren Zustandsveränderungen. Der Event Bus verteilt Events an alle Axon-gestützten Anwendungen, die den zugrunde liegenden Event-Typ konsumieren.

  3. Queries: Queries beinhalten die notwendigen Informationen, um Zustand abzurufen. Der Query Bus hat Load-Balancing-Fähigkeiten und verteilt eine Query entsprechend.

Location Transparency

Axon Server stellt die physische Infrastruktur und stützt damit den operationellen Betrieb einer Axon-gestützten Architektur. Axon Server übernimmt zwei wesentliche Aufgaben: Zum einen dient es als Event Store (im Sinne der Persistenzstrategie Event Sourcing), zum anderen als Message Broker, der Nachrichten zwischen Axon-Anwendungen verteilt. Die Anwendung kennt lediglich den URL des Axon Servers, an dem sie sich nach dem Start registriert. Die Kollaboration mehrerer Anwendungen geschieht transparent über den Axon Server, der das Routing von Commands, Events und Queries übernimmt.

Obwohl sich Axon Server bestens als Infrastrukturkomponente eignet, ist man nicht daran gebunden. Für das Axon Framework existieren Integrationen mit anderen Technologien, die die unterschiedlichen Rollen des Axon Servers übernehmen können. Darunter existiert eine Integration mit MongoDB als Event Store sowie Anbindungen von RabbitMQ oder Apache Kafka, die als Message Broker zum Einsatz kommen.

Entwicklung mit dem Axon Framework – so geht’s!

Eine Beispielanwendung soll die Kernkonzepte des Axon Frameworks verdeutlichen. Die fachliche Domäne für dieses Beispiel ist bewusst einfach gehalten und beschäftigt sich mit dem Anlegen und Schließen von Einträgen einer To-do-Liste. Abbildung 2 zeigt die grundlegende Architektur des Beispiels und ordnet die Verantwortlichkeiten des Axon Servers als Infrastrukturkomponente entsprechend ein. Die gezeigte Beispielanwendung verfolgt einen monolithischen Ansatz und nutzt als Persistenzstrategie Event Sourcing. Im Sinne von CQRS existieren für den schreibenden sowie lesenden Zugriff jeweils separate Schnittstellen. Die lesende Schnittstelle nutzt Projektionen auf Basis publizierter Events, um entsprechend den Abfragen der Schnittstelle optimierte Lesemodelle aufzubereiten. Das Dispatch Model des Axon Frameworks wird über Axon Server als Infrastrukturkomponente gestützt.

guenther_axon_2.tif_fmt1.jpgAbb. 2: Übersicht über die Architektur der Beispielanwendung

Eine anstehende Tätigkeit ist durch ein Item repräsentiert. Das Item besitzt eine eindeutige Kennung in Form einer ID und zusätzliche Attribute, die die Tätigkeit hinter dem Item genauer beschreiben: Einen Besch...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang