Dies ist der erste Teil einer Artikelserie zum Thema Architektur und Microservices.

Nachdem bei den Software Pionieren die ersten Projekte erfolgreich umgesetzt und von den Anwendern im produktiven Einsatz genutzt werden, spielen Themen wie Skalierung und Flexibilität eine immer wichtigere Rolle. Daher möchte ich in dieser Artikelserie den Weg vom derzeitigen API „Monolithen“ zur Microservice Implementierung beschreiben. Im Moment gibt es lediglich die beschriebene Ist-Situtation und einige Ideen wo die Reise hin gehen soll.

Bei den Software Pionieren setzten wir im Bereich der Server und API Programmierung von Anfang an auf die folgenden Design-Prinzipien bzw. Architekturen:

  • Command Query Responsibility Segregation (CQRS)
  • Domain Driven Design (DDD)
  • Event Sourcing (ES)

Dass diese Prinzipien, trotz noch nicht ganz „perfekter“ Architektur, sehr gut funktionieren sehen wir täglich: Im Projekt haben wir ca. 350 aktive Benutzer, die mittels einer von uns programmierten Smartphone App auf Daten zugreifen. Diese Daten werden durch eine zweite Browser-Applikation verwaltet.

Ich möchte im folgenden nicht bis ins Kleinste auf diese Prinzipien eingehen, sondern lediglich die aus meiner Entwicklersicht wichtigsten Vorteile aufzählen:

CQRS

Trennung von Lese- und Schreiboperationen: Eine Anwendung greift die meiste Zeit lesend auf die Daten zu. Die im Client zur Anzeige benötigten Daten werden für die Anzeige optimiert gespeichert und gelesen. Es wird also genau das gespeichert, was auch benötigt wird. Kombiniert mit serverseitigen Caching-Verfahren können so erstklassige Antwortzeiten erreicht werden.

Früher (zu Zeiten der relationalen Datenbankprogrammierung) sah dies anders aus: Es gab eine große SQL-Datenbank, in der ein allumfassendes, bis ins kleinste normalisiertes, Modell die Daten gespeichert hat. Mit Hilfe von Views und SQL-Queries wurden die sorgfältig normalisierten Daten wieder zusammen gefügt und in der Anwendung angezeigt.

Domain Driven Design

Die gesamte Steuerung der Logik (auf Schreibseite) findet zentral, an einer Stelle im Code, statt. Ein Command geht rein, darf abgelehnt oder ausgeführt werden. Events werden erzeugt und durch den Message-Bus geschickt, jemand anders reagiert drauf. Perfekt.

Früher durfte jeder mal in die Datenank schreiben, man war sich nie so richtig sicher, an welcher Stelle Schreiboperationen passierten.

Event Sourcing

Das Domänen Modell (das Aggregat) wird zur Laufzeit aus den gespeicherten Ereignissen aufgebaut. Der aktuelle Stand ist immer das Ergebnis der Folge aller aufgetretenen Events. Eine Historie wird direkt mit geliefert.

Früher wurde ein Update auf der Datenbank gemacht und das Objekt war geändert. Wie, und warum die Änderung zustande kam? Der Debugger hat es dir vielleicht verraten…. Ein Änderungs-Protokoll musste aufwendig programmiert werden.

Umsetzung

Die Programmierung der Server API’s erfolgt mit dem Microsoft .Net Core Framework und C#. Für die Kommunikation wird ASP.NET Core eingesetzt, hier aber im Wesentlichen nur der Web-API Teil. Die Frontends werden mit Angular implementiert (dazu wird es aber mit Sicherheit noch eigene Artikel geben). Innerhalb der Anwendungen kommen noch diverse Techniken wie SignalR, Swagger, etc. zum Einsatz.

Hosting

Wir hosten unsere Cloud-Projekte auf Microsoft Azure. Dabei kommen aktuell folgende Services zum Einsatz:

  • Azure Active Directory: Benutzerverwaltung und Anmeldung
  • Storage: Speicherung von Dateien
  • Cosmos Db: Speicherung des Read-Models
  • Virtual Machine: Hosting des Event Store Servers
  • Automation: Powershell DSC Provisioning des Servers
  • Recovery: Sicherung des Servers
  • App Service: Hosting der API
  • App Service Linux: Hosting der Client Apps mittels Docker Image, basierend auf nginx
  • Application Insights: Logging und Monitoring der API

Das Ganze sieht dann in Azure ungefähr so aus:

Es gibt eine Resourcen Gruppe für die Basis Resourcen:

ist-azure-1

Eine Resourcen Gruppe für die Virtual Machine Resourcen:

ist-azure-2

Eine Resourcen Gruppe für die API AppServices:

ist-azure-3

und noch eine für die Backend Client Apps:

ist-azure-4

Man sieht am kleinen Pinguin, dass hier ein Linux App Service Plan benutzt wird. Das kommt daher, dass die Backend Clients als Docker Container gehostet sind.

Im Moment ist es so, dass die einzelnen Stages (DEV, TEST, PROD) nicht als Slots, sondern als eigenständige App Services implementiert sind.

Ziel

Zukünftig soll es so sein, dass anstatt der App Services nur noch ein Managed Kubernetes Cluster läuft. Innerhalb dieses Clusters werden dann sämtliche Apps, Clients, Services und Microservices gehostet.

Deployment

Es ist eine vollständige CI / CD Pipeline mit Hilfe der Visual Studio Team Services implementiert. Es werden sowohl die Azure Resourcen, die DSC Konfigurationen, als auch die Anwendungen automatisiert verteilt.

Die Solution wird nach dem Push auf dem Master-Branch gebuildet, die Artefakte hochgeladen und anschließend startet automatisch der Release-Prozess. Es erfolgt das Deployment auf die Dev- und Testumgebung. Das Release zur Prod-Umgebung muss aktuell manuell freigegeben werden. Zusätzlich dazu kann der Prozess jederzeit im Dev-Branch manuell gestartet werden. Hierbei geht das Release allerdings nur bis zum Dev-Environment.

Hier sieht man die letzten Builds im VSTS:

vsts-build-1

und hier die Release Pipeline für die API mit den 3 Environments:

vsts-release-1

Fazit

Es gibt noch viel zu tun auf dem Weg zur „sauberen“ Micrososervice-Architektur. Es ist aber auch schon einiges geschafft.

Wir setzen diese Techniken erst seit gut 8 Monaten ein und haben von Grund auf neu damit begonnen. Die Performance ist sehr gut, dank CQRS und internen Caching auf Query-Seite. Die Logiken sind gut zu verstehen und zu erweitern, dank dem DDD auf der Command-Seite. Die DevOps Pipelines funktionieren und neue Versionen werden automatisiert installiert.

Ich würde mich freuen, wenn der ein oder andere den Weg mit mir geht. Bin auf Kommentare, Fragen und Diskussionen gespannt.
Schöne Grüße,
Tobias
Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s