All Posts By

Stefan Zörner

Softwarearchitektur SpeedDating JUG Karlsruhe

Softwarearchitektur Speed-Dating bei der JUG Karlsruhe

By | Publikationen, Vorträge | No Comments

JUG Karlsruhe


 „Monolith sucht Resilienz — Softwarearchitektur Speed-Dating“
Interaktiver Vortrag. Impuls und Moderation: Stefan Zörner

Veranstaltung bei der JUG Karlsruhe
Mittwoch, 13.Februar 2019
Synyx GmbH & Co. KG, Gartenstraße 67, 76135 Karlsruhe
#jugka

Foliendownload (PDF)

Zeitgemäße Softwarearchitektur ist nicht das Werk einzelner. Architekturansätze und Ideen entstehen im Team und werden gemeinsam reflektiert. Alle Entwickler müssen sie zumindest verstehen und mittragen können. Aber was genau müsst Ihr vermitteln? Reicht aufschreiben? Hilft UML?

Stefan Zörner zeigt auf lebendige Weise, wie Ihr Eure Softwarearchitektur wirkungsvoll kommunizieren könnt. Nach kurzen theoretischen Inputs rund um Architekturdokumentation und -bewertung probiert Ihr das Gehörte gleich aus. Ihr lernt die Lösungen anderer Teilnehmer kennen und erfahrt Schritt für Schritt, welche Zutaten in einem Architekturüberblick keinesfalls fehlen sollten – egal wie kurz er ist. Ihr lernt die richtigen Fragen zu stellen und passende Antworten parat zu haben.

Bringt bitte die Bereitschaft mit, Euch über Eure Projekte und Softwarelösungen auszutauschen, und anderen Teilnehmern Feedback zu geben. Die sonst üblichen Speed-Dating-Themen wie Ex-Partner und Kinderwünsche klammern wir aus.

Stefan Zörner - Monolith sucht Resilienz

Zur Veranstaltung

follow us on Twitter – @embarced

Artikel in Java aktuell: Microservices und Makro­-Architektur

By | Artikel, Publikationen | No Comments
Microservices und Makro­-Architektur

In der Ausgabe 01/2019 der Java aktuell ist ein Artikel zu Makro-Architektur und Microservices erschienen. Sie finden ihn hier als PDF zum Download.

Java aktuell 01/19 Cover

Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen
Autor: Stefan Zörner
Artikel in Java aktuell 01/2019
online erschienen am 27. Dezember 2018
Artikel-Download (PDF)

Moderne Architektur-Stile wie Microservices oder Self-contained Systems lassen Teams, die einzelne Teile entwickeln, viel Freiheit bei Technologieentscheidungen. Drei Themen entpuppen sich jedoch regelmäßig als Kandidaten, um übergreifend adressiert zu werden, damit die Anwendung wie aus einem Guss wirkt oder andere Architekturziele nicht verfehlt. Dieser Artikel stellt die Fragestellungen vor und zeigt Antworten auf.

Artikel als PDF follow us on Twitter – @embarced

IT-Tage 2018_SZoerner_embarc

IT-Tage 2018 – Was (genau) ist eigentlich Architekturbewertung?

By | Inhaltliches, Publikationen, Vorträge | No Comments
„Nörgeln ist einfach. Aber was (genau) ist eigentlich Architekturbewertung?“

IT-Tage 2018

Nörgeln ist einfach. Aber was (genau) ist eigentlich Architekturbewertung?
Sprecher: Stefan Zörner
Vortrag bei den IT-Tagen 2018
Dienstag, 11. Dezember 2018, ab 11:30 Uhr
Frankfurt am Main, im Kongresshaus Kap Europa

Foliendownload (PDF)



Statler: “Das war wirklich mal was zum Lachen!”
Waldorf: “Ja, das ist echt komisch gewesen!”
Statler: “Was glaubst Du – ob das beabsichtigt war?”
(aus der Muppet Show)


Jedes interessante Softwaresystem hat eine Softwarearchitektur. Diese ist kunstvoll geplant oder zufällig entstanden, meist aber irgendwas dazwischen. Hätte man es anders machen sollen? In diesem Vortrag stelle ich vor, wann und wie Ihr Eure Softwarearchitektur bewertet! Seid Ihr auf dem richtigen Weg? Können Eure Architekturideen in der Umsetzung aufgetretene Probleme effektiv lösen? Helfen diese bei der Erreichung Eurer Ziele oder behindern sie diese eher? Architekturbewertung kann Sicherheit schaffen und Risiken aufzeigen und damit helfen die Aufwände im Vorhaben zu fokussieren. Ihr lernt qualitative und quantitative Bewertungsmethoden kennen: Was argumentative, Workshop-basierte Verfahren wie ATAM leisten thematisiere ich ebenso wie welche Aspekte Eurer Architekturziele sich mit Messungen verknüpfen lassen.

Stefan Zörner - Stefan Zörner - Was (genau) ist eigentlich Architekturbewertung

follow us on Twitter – @embarced

Architekturbewertung. Artikel von Stefan Zörner in Informatik Aktuell

By | Artikel, Publikationen | No Comments
Nörgeln ist einfach. Aber was (genau) ist eigentlich Architekturbewertung?

Informatik Aktuell Logo

„Was ist eigentlich Architekturbewertung?“
Autor: Stefan Zörner
Artikel in Informatik Aktuell
online erschienen am 06. Dezember 2018

In Softwarevorhaben stellen insbesondere Neue im Team gerne Fragen wie: „Warum habt ihr das so gemacht? Wäre das nicht anders besser gewesen? Also ich hätte ja …“ – Was genau heißt dann „besser“. Nachher ist man immer schlauer. Und Nörgeln ist bekanntlich einfach … In diesem Artikel diskutiere ich, welche Ansatzpunkte und Methoden es zur Bewertung einer Softwarearchitektur gibt, und welche davon zu welchen Zeitpunkten im Leben einer Software Nutzen stiften.

Artikel Online Lesen

Zum Thema Architekturbewertung

follow us on Twitter – @embarced

JUG_Saxony_Day_2018

JUG Saxony Day 2018: Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen

By | Publikationen, Vorträge | No Comments
„Microservices & Makro-Architektur
Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen“

Logo JUG Saxony Day

Microservices & Makro-Architektur – Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen
Sprecher: Stefan Zörner
Vortrag auf dem JUG Saxony Day 2018
Freitag, 28. September 2018, 11:50 – 12.50 Uhr
Radebeul bei Dresden, im Radisson Blu Park Hotel & Conference Centre
#JSD2018

Foliendownload (PDF)

Rückblick JUG Saxony Day 2018 (auf Youtube)



Moderne Architekturstile wie Microservices oder Self Contained Systems lassen Teams, die einzelne Teile entwickeln, viel Freiheit beim Treffen von Technologieentscheidungen. Drei Fragestellungen entpuppen sich jedoch regelmäßig als Kandidaten, um in der Makro-Architektur (also übergreifend) adressiert zu werden, zumindest zu einem gewissen Grad. Sonst wirkt die Anwendung nicht aus einem Guss oder verfehlt andere Architekturziele (z.B. flexibel reagieren zu können auf Veränderungen). In diesem Vortrag stelle ich die drei Themen entlang eines durchgängigen Beispiels vor. Ich zeige gängige Lösungsoptionen und Einflussfaktoren, die Euch eine informierte Auswahl für Eure Vorhaben ermöglichen. Wechselseitige Beeinflussungen, Kompromisse und Real World-Entscheidungen eingeschlossen.

Stefan Zörner - Mikro- vs. Makroarchitektur

follow us on Twitter – @embarced

Microservices und Makroarchitektur

Vortrag auf dem Java Forum Nord im September in Hannover

By | Publikationen, Vorträge | No Comments
„Microservices & Makro-Architektur — Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen“

Logo Java Forum Nord

Microservices & Makro-Architektur –

Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen
Sprecher: Stefan Zörner
Vortrag auf dem Java Forum Nord 2018
Donnerstag, 13. September 2018
Hannover, Hotel Dormero, Hildesheimer Straße 34 – 38

Foliendownload (PDF)

Moderne Architekturstile wie Microservices oder Self-contained Systems lassen Teams, die einzelne Teile entwickeln, viel Freiheit beim Treffen von Technologieentscheidungen. Drei Fragestellungen entpuppen sich jedoch regelmäßig als Kandidaten, um in der Makro-Architektur (also übergreifend) adressiert zu werden, zumindest zu einem gewissen Grad. Sonst wirkt die Anwendung nicht aus einem Guss oder verfehlt andere Architekturziele (z.B. flexibel auf Veränderungen reagieren zu können).

In diesem Vortrag stellt Stefan Zörner die drei Themen entlang eines durchgängigen Beispiels vor. Er zeigt gängige Lösungsoptionen und Einflussfaktoren, die Euch eine informierte Auswahl für Eure Vorhaben ermöglichen. Wechselseitige Beeinflussungen, Kompromisse und Real World-Entscheidungen eingeschlossen.

Stefan Zörner - Mikro- vs. Makroarchitektur

MicroMoves_Bauteil 6

Einen Computergegner asynchron anbinden mit RabbitMQ (Micro Moves, Bauteil 6)

By | Inhaltliches | No Comments

Blog-Serie Micro Moves -- LogoIn der vorherigen Folge der Micro-Moves-Serie haben wir einen Service für die Spielregeln im Schach synchron an einen anderen Service angeflanscht. Mit diesem Bauteil zeigen wir nun asynchrone Kommunikation. Konkret ermöglichen wir es Benutzern unserer Online-Schachplattform FLEXess sich mit einem der ganz Großen im Computer-Schach zu messen.

Um was geht es — ein Überblick

Im Bild sieht es aus, als gäbe es dieses Mal gleich zwei Bauteile. Was die Anzahl Prozesse angeht stimmt das auch. Wir integrieren einen Computer-Spieler (Stockfish) und binden ihn via Messaging asynchron an das games-Modul an. Inhaltlich passiert am Ende aber nur eins: Unsere Benutzer können gegen den Ranglisten-Ersten (CCRL 40/40, Stand Juli 2018) im Computer-Schach antreten. Oder auch der Computer gegen sich selbst, wenn wir einfach nur zugucken wollen.

Überblick FLEXess, Bauteil 6

Computerschach

Ein Jahrhundertraum wie das Fliegen. Eine Machine bauen, die Menschen im Schach bezwingt. Seit Wolfgang von Kempelens berühmten Schachtürken um 1780 haben sich Menschen daran versucht. Das Problem können wir als gelöst ansehen. Claude Shannon hat 1949 mit seinem Aufsatz „Programming a Computer for Playing Chess“ die theoretische Grundlage gelegt. 1996 verlor das erste Mal ein amtierender Schachweltmeister — stellvertretend für die gesamte Menschheit sozusagen — unter Wettkampfbedingungen gegen eine Machine (Deep Blue). Mit dem aktuellen Megatrend Machine Learning hatte das Ganze übrigens nichts zu tun. Deep Blue lernte nicht. Es rechnete einfach brutal schnell.

Erste Schach-Computer für den privaten Gebrauch erschienen bereits 1977 und kosteten noch eine Stange Geld. Der Fortschritt in der Hardware lässt uns heute bequem auf unserem Smartphones gegen eine App verlieren. Der eigentliche (Rechen-)Kern von Schach-Programmen wird dabei als „Engine“ bezeichnet. Engines lassen sich typischerweise in verschiedene Schachoberflächen integrieren. Damit dies einfach möglich ist, und auch damit Engines leicht gegeneinander antreten können, haben sich textbasierte Kommunikationsprotokolle etabliert. Das verbreitetste heute ist UCI (kurz für Universal Chess Interface, Spezifikation siehe hier).Stockfish Logo

Um auch Nutzern von FLEXess die Möglichkeit zu geben, gegen einen ernstzunehmenden Computergegner anzutreten, binden wir in dieser Folge Stockfish an. Das ist eine besonders spielstarke Chess Engine, in C++ implementiert und Open Source. Stockfish ist auf allen Ranglisten vorne dabei (Spitzenreiter zum Beispiel in der CCRL 40/40, Computer Chess Rating Lists, Stand Juli 2018). Das Programm unterstützt das UCI-Protokoll und lässt sich dadurch einfach integrieren.

Stockfish auf der Kommandozeile

Wenn Ihr Stockfish für Eurer Notebook herunterladet findet Ihr auf der entsprechenden Seite auch ein einfaches UI, mit dem sich die Engine interaktiv passabel bedienen lässt. Uns interessiert allerdings die Kommandozeile. Startet Ihr die Stockfish Engine in einem Terminal könnt Ihr Befehle eingeben und die Denkarbeit des Programmes beobachten, inkl. des  „besten Zuges“ nach Ende einer Analyse. Die folgende Abbildung zeigt in einem Terminal, dass Stockfish ein Schäfermatt auch auf der Kommandozeile souverän nach Hause spielt.

Stockfish in der Kommandozeile

Die von mir eingegebenen Befehle waren isready, position, go und quit. Mit position wird die aktuelle Spielsituation gesetzt. Die Eingabe ist in FEN möglich (mit position fen …, Details zu dieser Notation findet Ihr in der zugehörigen Randnotiz). Oder wie oben im Bild durch Angabe der bisherigen Züge ausgehend vom Start (mit position startpos moves e2e4 e7e5 d1h5 …). Die verwendete Züge ermöglichen weiß am Zug ein sogenanntes Schäfermatt. Die schicke Abbildung unten zeigt das Brett nach diesen 6 (Halb-)zügen. Es ist übrigens mit dem chess-diagrams-Modul als Folge 2 dieser Serie generiert.

Spielsituation vor Schäfermatt

Der UCI-Befehl go lässt Stockfish losrechen. Mit dem depth-Parameter habe ich die Suchtiefe beschränkt, damit die Ausgaben nicht das Terminal zutexten und wir die vorherigen Eingaben noch im Screenshot sehen. Mit bestmove gibt Stockfish seinen Zug aus. Dame auf h5 schlägt auf f7 und setzt Matt. Besser geht es nicht.

Mit quit können wir die Session beenden. Wir wollen Stockfish nicht weiter unterfordern.

Stockfish anbinden

Roboter mit SteckerBei der Integration der Schach Engine habe ich mich für Python entschieden, um ein bisschen Gluecode zu schreiben. Ihr findet diesen im Modul computer-player auf GitHub. Die betreffende Datei heißt stockfish.py und umfasst ca. zwei Dutzend Zeilen Quelltext. Die Python-Funktion calculate_move startet Stockfish als Subprozess. Via stdin gibt sie die Befehle (position, go …) an die Engine und holt sich das Ergebnis über dessen stdout ab.

Das Ganze funktioniert nur, wenn stockfish installiert ist. Ein kleiner Integrations-Test mit tox überprüft die Anbindung der Engine, indem er Stockfish u.a. genau das Schäfermatt serviert. Unser Image für Docker basiert auf Ubuntu. Das Dockerfile installiert Stockfish mit apt-get. Damit das Programm aktiv wird, wenn wir ihm Züge vorlegen, verbinden wir es via Messaging.

Die Messaging-Renaissance

Messaging ist eine etablierte Technologie, um Programme miteinander sprechen zu lassen, die dies von Natur aus nicht können. Entsprechende Middleware schaut auf eine lange Geschichte zurück. WebSphere MQ von IBM etwa erblickte als MQSeries bereits Anfang der 90er das Licht der Welt. Der spätere SOA-Hype befeuerte den Einsatz derartiger EAI-Lösungen. Neben kommerziellen Produkten von Firmen wie Oracle oder TIBCO gibt es auch Open Source-Lösungen, etwa Apache ActiveMQ.

RabbitMQ LogoMessaging-Lösungen kennzeichnen sich durch lose Kopplung aus. Die Kommunikationspartner können in sehr verschiedenen Technologien implementiert sein und auf unterschiedlichsten Plattformen laufen. Der Nachrichtenaustausch erfolgt asynchron und oftmals indirekt. Die Partnerprogramme brauchen sich weder kennen, noch gleichzeitig laufen. Das macht Messaging Lösungen für zeitgenössische Architekturstile wie Microservices, die lose Kopplung anstreben, sehr interessant.

Auch wenn die Konzepte die alten sind sehen wir vermehrt neuere, leichtgewichtige Messaging-Löungen auf dem Vormarsch. Ganz vorne dabei ist RabbitMQ. Die in Erlang entwickelte Open Source-Lösung implementiert eine Reihe von Standards, darunter AMQP (Advanced Message Queuing Protocol).

Für unsere Anbindung haben wir ein vorgefertigtes Docker-Image von RabbitMQ genutzt, und in der Konfigurationsdatei für docker-compose als Service vereinbart. Die gewählte Image-Variante beinhaltet die webbasierte Management-Konsole. Dadurch lässt sich RabbitMQ mit seinen Verbinden, Nachrichtenaustauschen und Queues prima von außen beobachten. Die folgende Abbildung zeigt bereits unser FLEXess in Aktion. Also beim Senden und Empfangen von Schachstellungen und Spielzügen als Nachrichten.

RabbitMQ Management Console

games und computer-player tauschen Nachrichten aus

Für die Anbindung zwischen games und computer-player (siehe auch Überblicksbild oben) nutzen wir zwei sogenannte „Direct Exchanges“ in RabbitMQ. Die Middleware bietet verschiedene Austauschmuster an — das direkte ist das einfachste. Die folgende Abbildung zeigt das Zusammenspiel:

Ablauf Messaging

Zwei Queues nehmen Nachrichten im JSON-Format auf. Im Fall eines Zuges, den Stockfish ausführen soll, legt games zunächst eine Nachricht mit der Spielsituation (Schachstellung in FEN) in der Message-Queue positions ab. Ein Computer-Spieler „lauscht“ auf dieser Queue (Implementierung der Funktionen in Python in der Datei stockfish_listener.py). Tatsächlich könnte es mehrere computer-player-Container  geben. Im Falle einer Nachricht liest computer-player die Position aus und nutzt die UCI-Integration wie oben beschrieben zur Ermittlung des besten Zuges aus Stockfishs Sicht. Dieser Zug geht über die Queue moves an games zurück. Über die Game-ID, die jede Nachricht als ein Attribut enthält, kann das games-Modul den Zug dem Spiel zuordnen und ausführen.

Die Aussteuerung von Spielsituationen in die Warteschlange positions erfolgt in games über den Spielernamen „stockfish“. So kann ein Spieler gegen den Computer spielen, indem er einfach eine Partie gegen „stockfish“ startet. Die folgende Abbildung zeigt mich (weiß) im Spiel gegen den Computer-Gegner. Im Moment sieht es noch ausgeglichen aus.

Spiel gegen den Computer-Gegner im Browser

Übrigens lassen sich über das UI des games-Subsyststems auch Partien starten, in denen Stockfish gegen sich selbst spielt. Einfach für beide Spielernamen „stockfish“ im Formular unter „Create a new game“ eintragen. Dann geht das los. Wählt Ihr „Play Game!“ könnt Ihr die „beiden“ Kontrahenten beobachten. Die folgende animierte Abbildung zeigt den Ausschnitt einer solchen Partie in Endlosschleife.

Stockfish gegen Stockfish

Weitere Informationen. Und wie es weiter geht.

Enterprise Integration Patterns: Designing, Building, and Deploying Messaging SolutionsRabbitMQ stellt exzellente Tutorials für alle denkbaren Programmiersprachen und verschiedene Kommunikationsmuster bereit. Ich habe mich für Python daran orientiert. Für die Integration in das games-Modul mit Spring Boot ließ ich mich von einem entsprechenden Beitrag inspirieren: „Getting Started: Messaging with RabbitMQ“.

Die fundierte Quelle für Messaging in Buchform ist meiner Meinung nach immer noch der Klassiker Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions von Gregor Hohpe.

Die Entwicklung von Programmen, die Schach spielen können, geht weiter. Auch heute noch treten Schachprogramme im Wettbewerb gegeneinander an. Mittlerweile mischt die künstliche Intelligenz tatkräftig mit. 2017 schlug Google’s AI-Lösung AlphaZero das traditionelle Spitzenprogramm Stockfish. Es benötigte 4 Stunden, um Schach zu lernen. Und verlor im Anschluss von 100 Partien keine einzige (Bericht hier).

Wie geht es hier mit FLEXess weiter eigentlich? Die Benutzer brauchten sich bisher noch nicht an der Plattform anmelden. Eine Zeichenkette für den Spielernamen einzugeben, genügt. Und jeder kann bei jedem mitspielen. Zeit, dass wir uns diesem offensichtlichen Mangel widmen!

Ach ja: Fragen und Anregungen sind natürlich jederzeit gerne willkommen. Per Kommentar hier im Blog oder gerne auch per Mail direkt an mich …

Zur Blog-Serie Micro Moves
 

 

 

 

Stefan Zörner im Juli bei der Java User Group Münster

By | Publikationen, Vorträge | No Comments
„Mikro- vs. Makroarchitektur – Spielraum und Spielregeln“

JUG Münster Logo

Mikro- vs. Makroarchitektur – Spielraum und Spielregeln
Sprecher: Stefan Zörner
Vortrag bei der Java User Group Münster
Mittwoch, 4. Juli 2018, 18:30 – 20:30 Uhr
Anmeldung über Xing
LVM Versicherung, Kolde-Ring, Münster

Foliendownload (PDF)

Während in einer klassischen Konzern-IT Standards und Blaupausen für immer gleiche Anwendungsarchitekturen sorgen, betonen Microservice-Ansätze die technologische Freiheit. Zwei extreme Spielarten der Ausgestaltung von Makro- und Mikroarchitektur.

In diesem Mix aus Vortrag und kurzen interaktiven Elemente lernt Ihr neben dem Konzept selbst auch die auf Eure Ziele abgestimmte Richtung, die Ihr in dieser Fragestellung einschlagen solltet. Wie sieht in Eurem Kontext die Balance aus – was gebt Ihr für alle Elemente Eurer Anwendung(slandschaft) vor, wo lasst Ihr bewusst Spielraum? Und gibt es auch noch etwas dazwischen? Zu diesem Zweck passen wir organisatorische und technologische Trends wie 2-Speed/Bimodale Architekturen, Cloud und Domänenorientierung in das Entwurfsdoppel Makro und Mikro ein.

Stefan Zörner - Mikro- vs. Makroarchitektur

Beitragsbild_Bauteil_5

Spielregeln für Schach und für robuste Aufrufe mit Hystrix (Micro Moves, Bauteil 5)

By | Inhaltliches | No Comments

Blog-Serie Micro Moves -- LogoMittlerweile (seit dem dritten Teil dieser Serie) könnt Ihr auf unserer Online-Schachplattform FLEXess Schach spielen. Allerdings ist die Überprüfung der Züge bzgl. der Spielregeln rudimentär. Solange die Figur die richtige Farbe hat, kann sie ziehen, wohin sie will. Im Extremfall auch quer übers Brett direkt auf den gegnerischen König. Weiterhin merken wir nicht, wenn eine Partie zu Ende ist. Wir führen in diesem Teil einen neuen Service ein, der die Spielregeln anbietet. Und nutzen ihn aus dem games-Modul, um diese Mängel zu beheben.

Um was geht es — ein Überblick

Die komplizierten Spielregeln führen zu einem Quelltext-mäßig umfangreichen Bauteil rules. Wir implementieren es in JavaScript. Das Modul stellt seine Funktionalität per HTTP bereit. In Anlehnung an den letzten Teil der Serie machen wir sie im Reverse Proxy bekannt und bauen ein Docker-Image dazu, das wir in Docker Compose integrieren. Die rote (5) in der folgenden Abbildung markiert den Standpunkt von rules im Gesamtbild („Sie befinden sich hier.“).

Erster Verwender des Moduls ist das Partien-Subsystem games, das überprüfen möchte, ob z.B. aus play eingehende Züge regelkonform sind. Und wissen will, ob eine Partie bereits beendet ist (Stichworte: Schachmatt, Patt). Hierzu greift es auf rules zu; der Zugriff erfolgt synchron. Wir sichern ihn mit Netflix Hystrix ab (Stichwort Resilience).

Aber der Reihe nach …

Spielregeln im Schach — und warum ein eigenes Modul?

Die Schachregeln sind verglichen mit anderen Spielen wie Dame oder Mühle vergleichsweise umfangreich. Es gibt sechs Figurenarten, die unterschiedlich ziehen. Der Bauer ist besonders kompliziert. Er schlägt anders als er zieht, darf am Anfang zwei Felder vor, mitunter en Passant schlagen und verwandelt sich auf der gegnerischen Grundlinie in eine andere Figur (engl. Promotion, für die englischen Schachbegriffe siehe diese Randnotiz). Darüber hinaus gibt es noch die Rochade, Schachmatt und Patt, die Regel, dass man nach seinem Zug nicht im Schach stehen darf … usw.

SchachfigurenEine vollständige Implementierung der Regeln ist aufwändig, aber nicht wirklich schwierig. Als nützlich erweist sich dabei eine Funktion, die für eine beliebige Position (im Wesentlichen die Platzierung der Figuren auf dem Brett, gegeben etwa in Forsyth-Edwards-Notation, siehe Randnotiz dazu) die Liste aller erlaubten Züge des am Zug befindlichen Spielers ermittelt. Mit dem Ergebnis könnt Ihr etwa prüfen, ob ein gegebener Zug gültig ist (er muss in der Liste auftauchen). Ist die Zugliste leer ist das Spiel beendet. Ob der König am Zug angegriffen ist macht dann den Unterschied aus zwischen Matt (verloren) und Patt (unentschieden aka Remis).

Die Spielregeln lassen sich prima automatisiert testen. Insbesondere die Funktion welche die gültigen Züge ermitteln. Auch hier leistet die Forsyth-Edwards-Notation gute Dienste, da man mit ihr in Unit-Tests sehr einfach die Eingabe als Zeichenkette repräsentieren kann. Hier ein Code-Fragment wie es in etwa in unseren Unit-Tests auftaucht

fen = "8/8/7R/3k4/8/3P4/7B/7K b - - 0 1"
expectedMoves = ["d5d4", "d5c5"]
pos = new Position(fen)
moves = ChessRules.getAllValidMoves(pos)
assert.equal(moves.length, expectedMoves.length)
...

In unserem Überblicksbild erkennt Ihr mögliche Verwender für Schachregeln. Neben dem Partien-Service games etwa die beiden Clients play (in Vue.js aus Folge 3) und später noch den Mobile Client. Diese Clients würden durch Nutzung der Spielregeln die Benutzbarkeit erhöhen, in dem sie etwa beim Auswählen einer Figur die Felder markieren, wo die Figur hinziehen darf. Und sie könnten einen eingegebenen Spielerzug prüfen, bevor sie ihn Richtung games schicken, und so den Server entlasten und unnötigen Netzwerkzugriffe (bei fehlerhaften Zügen) vermeiden.

Alternatives Schach: Neue Regeln für das Spiel der KönigeWenn jeder Client die Spielregeln selbst implementieren würde, ständen diesen Vorteilen der Nachteil des mehrfachen Aufwands gegenüber und die Gefahr von Inkonsistenzen. Wenn wir die Spielregeln später ergänzen wollen, um auch so schöne Varianten wie Atom-Schach oder Zombie-Schach zu unterstützen, müssten wir an verschiedenen Stellen Änderungen vornehmen. Schöne Anregungen für alternative Schachregeln finden sich übrigens im Buch rechts …

Die Spielregeln zentral zu entwicklen und als Bibliothek zur Verfügung zu stellen (vgl. Shared Kernel in DDD) wäre eine Option. Als problematisch könnten dabei unterschiedliche Programmiersprachen herausstellen. Eine weitere Möglichkeit wäre die Spielregeln im games-Modul zu integrieren. Ich habe mich dagegen entschieden, da dieses Modul eh schon recht groß ist, und ich es ungern neu deployen möchte, um neue Spielregeln zu unterstützen.

Die Wahl fiel daher auf einen eigenen Service rules, der die Spielregeln über eine HTTP-Schnittstelle bereitstellt. Im ersten Wurf nur Standard-Schach allerdings, kein Zombie-Schach.

Implementierung in JavaScript

Die für Micro Moves erstellte Implementierung der Spielregeln in JavaScript (Quelltext auf GitHub) benutzt folgendes Domänenmodell (folgende Abbildung). Die Felder des Brettes werden als Zahlen von 0..63 repräsentiert. Die zentrale Klasse Position spiegelt den Zustand einer Partie wider und orientiert sich an FEN. Objekte sind unveränderlich, die Methode performMove liefert eine neue Position mit der geänderten Spielsituation zurück.

Alle oben dargestellten Elemente finden sich in der Quelltextdatei domain.js. Die folgende Tabelle gibt einen Überblick über alle Dateien der Implementierung.

Datei Wesentliche Elemente Beschreibung
domain.js Colour, Move, Position Domänenmodell für die Schachelemente
geometry.js BoardGeometry Geometrie des Schachbretts, inkl. Bewegungen gerade, schräg …
rules.js ChessRules gültige Züge, angegriffene Felder, Schachmatt …

Für die Spielregeln liegen im Unterverzeichnis tests des Moduls eben solche. Realisiert sind sie mit dem Test-Framework Mocha, siehe etwa „Simple Node.js tests with assert and mocha“. Ihr führt sie einfach mit npm test aus, der folgende Screenshot zeigt einen Teil der Ausgabe:

"npm test" in rules (Ausschnitt)

Die folgende Tabelle skizziert die Operationen der Klasse ChessRules jeweils anhand Eingabe und Ergebnis.

Funktion Eingabe Ergebnis
getAllValidMoves Position Liste der aus der Postion heraus möglichen Züge für den aktiven Spieler
isSquareAttackedByColour Position, Feld, Farbe boolean, ob das Feld in der Postion von einer Figur der betreffenden Farbe angegriffen ist
isCheckmate Position boolean, ob die gegebene Position ein Schachmatt für den aktiven Spieler ist.
isStalemate Position boolean, ob die betreffende Position ein Patt ist.

Der Spielregeln-Service

Logo expressDer eigentliche Service für die Spielregeln ist mit Node.js und dem Framework Express realisiert. Express bezeichnet sich selbst als schnelles, offenes, unkompliziertes Web-Framework für Node.js. Im ersten Wurf unterstützt der Service nur zwei Funktionen. Über die URL /allValidMoves könnt Ihr zu einer Position (Request-Parameter fen) die Menge der möglichen Züge ermitteln (entspricht der Funktion getAllValidMoves aus den Regeln oben). Weiterhin ist es mit /validateMove möglich eine Position (Request-Parameter fen) und einen Zug (Request-Parameter move) anzugeben. Zurückgeliefert wird ein JSON-Dokument, das einen Boolean-Wert enthält, ob der Zug gültig ist. Weiterhin im Falle eines gültigen Zuges die neue Position nach Ausführung (in FEN), und ob diese Position ein Schachmatt ist oder ein Patt. Hier ein Beispiel-Resultat für einen Aufruf:

{
  "fen":"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
  "move":"e2e4",
  "valid":true,
  "resultingFen":"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1",
  "checkmateAfterMove":false,
  "stalemateAfterMove":false
}

Der Quelltext für den Service findet sich in der Datei server-main.js. Start mit npm start. Der Service enthält eine index.html als statische Testseite. Dort sind einige Aufrufe für die Funktionen verlinkt, damit Ihr sie direkt ausprobieren könnt, ohne selbst Aufrufe mit fen und move als URL-Parameter zu basteln. Die folgende Abbildung zeigt einen Screenshot der Seite, inkl. JSON-Ausgabe bei Aufruf eines Test-Links.

Testseite rules, inkl. Aufruf mit JSON-Ausgabe.

Das rules-Modul enthält darüber hinaus ein Dockerfile (vgl. Folge 4) und ist in die Docker Compose-Konfiguration von FLEXess integriert. Der Artikel „Dockerizing a Node.js web app“ erklärt kurz und knackig wie Ihr Docker Images für Node.js-Anwendungen baut. Ich habe mich daran orientiert.

Synchrone vs. asynchrone Kommunikation

Mit der neuen Funktionalität wäre das games-Modul nun in der Lage, eingehende Züge bzgl. der Spielregeln zu überprüfen. Weiterhin könnte es die neue Spielsituation aus dem Zug ermitteln, und ein Spielende durch Matt oder Patt erkennen.

Immer wieder Thema im Zusammenhang mit vertikalen Architekturstilen ist die Kommunikation zwischen Teilen, in unserem Fall also zwischen games und rules. Oftmals etabliert bereits die Makroarchitektur Regeln oder Prinzipien. Ist Kommunikation zwischen Vertikalen überhaupt erlaubt? Falls ja: synchron, asynchron oder je nach Fall beides. Hinzu kommen Entscheidungen zu Protokollen und Technologien.

All diese Optionen haben Vor- und Nachteile, die je nach Fall mehr oder weniger ins Gewicht fallen (sonst würde da nicht so breit diskutiert). In FLEXess legen wir hier keinen allgemeinen Regeln fest, sondern zeigen in verschiedenen Folgen unterschiedlichen Ansätze. Und diskutieren diese.

In unserem Fall wirkt die Wahl einer synchronen Kommunikation natürlich: Bei games geht ein Zug zu einer Partie ein. Das games-Modul prüft mit einem Aufruf gegen rules, ob er regelkonform ist, und wartet auf das Ergebnis (synchron). Je nach Ausgang der Überprüfung wird der Zug ausgeführt und persistiert, oder abgelehnt. in jedem Fall erhält der Aufrufer ein Ergebnis (auf das er solange wartet).

Motivation für die synchrone Kommunikation ist hier, dass games ohne die Überprüfung in rules den Zug nicht annehmen oder ablehnen kann. Gleichzeitig warten auf der Client-Seite zwei Spieler auf diese Entscheidung. Und bei einem liefe in einem echten Spiel die Schachuhr für seine Bedenkzeit weiter. Wir brauchen das Ergebnis jetzt.

Sequenz-Diagramm zur synchronen Kommunikation zwischen games und rules

Größter Nachteil der synchronen Kommunikation, und der Grund warum in Microservices-Architekturen asynchrone Kommunikation (also das Versenden nach Nachrichten ohne Warten auf Reaktion) bevorzugt sind, ist die höhere Kopplung. Das nicht zur Verfügung stehen von rules führt dazu, dass games keine Züge annehmen kann. Wir kommen darauf noch zurück!

Anbindung an das games-Modul

Im games-Modul kümmert sich die Klasse RulesClient (im Packet org.flexess.games.rulesclient, Quelltexte siehe GitHub) um die Anbindung an rules. Sie fungiert als Gateway (vgl. Pattern-Buch von Martin Fowler) und bietet zunächst nur die Methode validateMove (analog zur URL im Service) an.

Die Klasse kapselt den HTTP-Aufruf gegen rules und das Überführen der JSON-Anwort in ein geeignetes Java-Objekt (Klasse ValidateMoveResult). Als HTTP-Client nutze ich Java-Bordmittel aus java.net. Auf eine Service Registry verzichten wir wie hier — das rules-Modul (und ggf. auch mehrere Exemplare davon) ist durch Docker Compose im Docker-internen Netzwerk mit dem Hostnamen „rules“ erreichbar.

Der RulesClient landet per Dependency Injection im GamesService, der ihn im Rahmen der Operation createAndPerformMove heranzieht, um den eingehen Zug auf Regelkonformität zu überprüfen. Ungültige Züge quittiert er (wie zuvor) mit einer Exception, die der REST-Service als Fehlermeldung zum Client (z.B. die Vue.js SPA play) sendet, siehe Screenshot:

Illegaler Zug, dargestellt in play-SPA

Bei Problemen im RulesClient (z.B. rules-Service nicht verfügbar) kommt es zu IOException u.ä., die innerhalb des RulesClient behandelt dem Service als RuntimeException weitergereicht werden könnten. Sonderlich robust ist das nicht.

Resilience mit Netflix Hystrix

Der synchrone Ansatz birgt die Gefahr, dass ein Ausfall des Moduls rules die Arbeit des zentralen Moduls games massiv behindert. Auch wenn rules für die Bearbeitung von Anfragen lange braucht, zieht das games in Mitleidenschaft. Bei vielen parallelen Anfragen könnte der Thread-Pool von games für HTTP-Anfragen leerlaufen. games antwortet dann nicht nur (auch) langsam, sondern gar nicht mehr (Connection refused) — selbst bei Anfragen, welche die Spielregeln gar nicht betreffen!

Release It!: Design and Deploy Production-Ready SoftwareArchitekturmuster rund um Resilience (dt. „Unverwüstlichkeit“) zielen auf robuste, fehlertolerante Systeme ab. Hier reisst ein einzelnes Teilsystem nicht gleich die ganze Anwendung runter. In Microservices-Anwendungen, in denen synchrone Kommunikation zwischen Services lt. Makro-Architektur zulässig ist, ein wichtiger Punkt. Der Self-contained Systems-Ansatz (kurz SCS, siehe Charakteristiken) hingegen propagiert asynchrone Kommunikation zwischen SCSen, wo immer möglich.

Dort, wo synchrone Kommunikation zwischen Services in der Makroarchitektur zulässig ist (Paradebeispiel: Netflix) hat sich das Circuit Breaker-Pattern etabliert. Es orientiert sich an der Metapher des Schutzschalters in Stromkreisen. Im Falle von Überlast fliegt dort die Sicherung raus und verhindert dass etwa Brände durch überhitzte Leitungen entstehen. Circuit Breaker schützt den Zugriff auf externe Systeme, z.B. einen anderen Service. Antwortet dieser nicht oder langsam, wird der Schaltkreis unterbrochen. Der Service erhält keine Anfragen, bis sich die Situation beruhigt hat (was mit einzelnen Aufrufen ab und an getestet wird).

Martin Fowler beschreibt das Muster in einem Blog-Beitrag — wie für Muster üblich ist die kanonische Quelle allerdings ein Buch: der resilience-Klassiker „Release It!“ von Michael Nygard (Cover rechts). Die zweite Ausgabe ist in 2018 frisch erschienen.

Logo HystrixAls konkrete Implementierung im Java-Umfeld stellt Netflix Hystrix als Bibliothek bereit. Es bezeichnet sich selbst als Latenz- und Fehlertoleranzlösung für verteilte Systeme. Für andere Programmiersprachen gibt es ähnliche Lösungen. Hystrix lässt sich über die Integration von Spring Cloud leicht in unser bestehendes games-Modul aufnehmen.

Um eine Operation (hier den Aufruf des rules-Service aus games) mit Hystrix abzusichern gibt es zwei Optionen. Entweder Ihr schreibt eine Command-Klasse gemäß der Hystrix-API, oder Ihr nutzt eine spezielle Annotation @HystrixCommand und „markiert“ damit eine Methode. Spring wickelt dann gemäß AOP einen Proxy und umhüllt die Ausführung. Letzteres ist die einfachere Variante, Ihr findet den Quelltext dazu im games-Modul in den Klasse RulesClient. Dekoriert ist dort die Methode validateMove.

Falls rules nun nicht zur Verfügung steht oder langsam antwortet öffnet sich der Kreis, und rules wird nicht von weiteren Anfragen von games belästigt. Mit dem Hystrix Monitor lässt sich das Verhalten von außen beobachten (bei geeigneter Konfiguration — das Dashboard muss an den Stream kommen …). Im Folgenden Screenshot seht Ihr unsere anmontierte Methode einmal mit geschlossenem Stromkreis (links), einmal mit unterbrochenem.

Hystrix Dashboard

Egal ob Ihr ein Command schreibt oder die Annotation nutzt: Ihr könnt einen Fallback implementieren bzw. angeben, der bei einem unterbrochenen Stromkreises greift. In der Regel kommt hier ein Default-Verhalten zum Einsatz, das weniger Schmerzen bereitet als ein Fehler. Beispielsweise könnten alte Werte aus einem Cache zurückgeliefert werden, wenn ein entferter Service gerade nicht zur Verfügung steht, und das fachlich akzeptabel ist. Klassisches Beispiel hier sind Wetterdaten, wo der Aufrufer ggf. auch gut mit älteren leben kann.

Im Falle unserer Schachregeln habe ich auf eine Alternative verzichtet. Der Aufrufer erhält die Nachricht, dass der Zug nicht überprüft werden konnte. Der folgende Screenshot zeigt die Situation in der Vue.js-SPA play.

Meldung: Rules service not available.

Denkbar wäre auch im Fall der Nichtverfügbarkeit der Spielregeln den gegnerischen Spieler entscheiden zu lassen, ob der vorgelegte Zug regelkonform ist oder nicht. Im echten Schachspiel ist es ja auch so (man weist den Gegner auf einen fehlerhaften Zug hin). Die Idee gefällt mir. Auf eine Implementierung habe ich trotzdem verzichtet.  

Weitere Informationen. Und wie es weiter geht.

Understanding ECMAScript6: The Definitive Guide for JavaScript Developers (Cover)JavaScript hat durch Technologien wie Node.js oder Single Page Applikations deutlich an Relevanz gewonnen, auch im Unternehmensumfeld. Es geht nicht mehr darum klassischen HTML-Anwendungen mit ein bisschen Feenstaub in Form von browser-seitigem Scripting ein wenig mehr Interaktivität einzuhauchen. Stattdessen entstehen größere Softwarelösungen in dieser Sprache mit einem ganz eigenen, reichen Öko-System. Das Javascript von 1995 hat mit dem von heute nicht mehr viel zu tun. Hingegen waren meine JavaScript-Kenntnisse lange durch diese alten Erinnerungen geprägt. Ein Buch, das mir geholfen hat wieder Anschluss an das „zeitgenössische“ JavaScript zu finden ist „Understanding ECMAScript6: The Definitive Guide for JavaScript Developers“ von Nicholas Zakas (Cover siehe rechts).

Nachdem in dieser Folge die synchrone Kommunikation Thema war, zeigen wir als Alternative dazu später noch einen asynchronen Fall mir Messaging. Eine weiterer offener Punkt ist Security. Im Moment könnte jeder Benutzer an jedem Brett ziehen (er müsste nur auf die Partie klicken).  In der Realität würden die tatsächlichem Spieler einem auf die Finger hauen. Später übernimmt das unsere Plattform.

Ach ja: Fragen und Anregungen sind natürlich jederzeit gerne Willkommen. Per Kommentar hier im Blog oder gerne auch per Mail direkt an mich …

Zur Blog-Serie Micro Moves

Spicker7_ContinousDelivery

Architektur-Spicker Nr. 7: Continuous Delivery

By | Publikationen, Spicker | No Comments
Architektur-Spicker Nr. 7: Continuous Delivery

Architektur-Spicker


Architektur-Spicker Nr. 7: Continuous Delivery
Autoren: Sandra Parsick & Stefan Zörner
Referenzkarte bei architekturSPICKER PDF, 6 Seiten
Erschienen 7. Juni 2018

Download Spicker #7

Die aktuelle Ausgabe unseres Architektur-Spickers bringt zeitgemäße Techniken aus Continuous Integration (CI) und Continuous Delivery (CD) kurzgefasst zusammen und zeigt wie wichtige Architekturziele wie Stabilität und Reaktionsfähigkeit damit unterstützt werden. Der Aufbau einer passenden CI/CD-Kette bildet den ‚roten Faden‘ hierzu.


In dem sechsseitigen PDF gehen wir unter anderem auf die folgenden Fragen ein:
  • Wie startet man den Aufbau einer CI/CDKette?
  • Moderne Architekturansätze wie Microservices haben hohe Anforderungen bzgl. Integration und Verteilung. Welche Wechselwirkungen bestehen zwischen Architekturstil und CI/CD?
  • Neue Features in eure Lösung zu integrieren ist aufwändig und fehleranfällig. Wie minimieren Sie dieses Risiko?

 

Architektur-Spicker 1-7


Architektur-Spicker #7

 

follow us on Twitter – @embarced