Self-Contained Systems

In diesem Artikel möchte ich erklären, was ein Self-Contained System ist, warum und wann es als Software-Architektur sinnvoll sein kann. Außerdem möchte ich darauf eingehen, wie der Einsatz dieser Architektur die parallele Entwicklung unterstützt.

Was ist ein Self-Contained System?

The Self-Contained System (SCS) approach is an architecture that focuses on a separation of the functionality into many independent systems, making the complete logical system a collaboration of many smaller software systems. This avoids the problem of large monoliths that grow constantly and eventually become unmaintainable. Over the past few years, we have seen its benefits in many mid-sized and large-scale projects.

Laut dieser Definition von http://scs-architecture.org/index.html sind SCS also der Versuch, große Softwaremonolithen in kleine, unabhänginge Systeme zu unterteilen. Das folgende Bild veranschaulicht das. [2]

Creating-first-SCS-01-1

Die dabei entstehenden SCSs sollen einige Eigenschaften erfüllen, damit diese Architektur auch in der Praxis erfolgreich ist:

  • Vertikaler Schnitt mit Frontend, Backend, Datenhaltung
  • Kommunizieren mit anderen SCSs, wenn nötig, asynchron über APIs
  • Teilen keine Geschäftslogik mit anderen SCSs
  • Teilen keine Infrastruktur mit anderen SCSs
  • Gemeinsame (technische) Bibliotheken können genutzt werden, z.B. oAuth Client
  • Ein SCS ist „klein genug“, dass es von einem Team betreut werden kann
  • Ein SCS wird nur von einem Team betreut
  • Möglichst viele Faktoren des 12factor-manifests: https://12factor.net/de/

An dieser Stelle möchte ich hervorheben, dass durch asynchrone Kommunikation und verteilte Geschäftslogik besonderes Augenmerk auf eventual consistency gelegt werden muss.
In der Praxis wird es nicht immer möglich sein, Laborbedingungen herzustellen und alle Eigenschaften zu 100% zu erfüllen.
Es gibt aber ein paar Regeln, die sollten auf keinen Fall verletzt werden. Wenn man sich beispielsweise eine Datenbank mit einem anderen SCS-Team teilen muss, ist das eher ein Indiz dafür, dass man den falschen Schnitt gewählt hat. Ansonsten fährt man bei Einhaltung der oben genannten Eigenschaften ganz gut auf dem Highway zur SCS-Landschaft.

Warum sollten wir Self-Contained Systems bauen?

Es gibt viele Gründe, warum SCSs eine coole Software-Architektur sind. Ein paar möchte ich hier aufzählen.

Isolation

Fällt ein SCS aus, können die anderen trotzdem weiterlaufen. Auch aus Security-Perspektive betrachtet: ist ein SCS gefährdet, heißt das noch nicht, dass alle gefährdet sind.

Technologien ausprobieren

Um immer am Zahn der Zeit zu bleiben, probieren Developer gerne rum. Am liebsten jeden Tag etwas neues probieren, das wäre was. Leider birgt das Einsetzen von neuen Technologien auch Risiken. Da kommt es doch gerade gelegen, wenn man argumentieren kann, dass jetzt nicht die ganze Firma Scala und Polymer lernen muss, sondern der "Schaden" sich maximal auf ein SCS begrenzt. Und da so oder so nur über APIs gesprochen wird, ist es doch auch egal, was da unter der Haube läuft.

Skalierung

Da sich SCSs optimalerweise keine Infrastruktur teilen und möglichst wenig mit anderen SCSs kommunizieren, lässt sich sehr leicht skalieren indem zusätzliche Instanzen eines SCS hochfährt.

Austauschbarkeit

SCSs kapseln lediglich bestimmte Fachlichkeit und erst ihr Verbund macht das Gesamtsystem aus. Dadurch kann sehr einfach ein einzelnes SCS ausgetauscht werden, was Risiko erheblich reduziert und z.B. Migrationen erleichtert.

Teams

Ein SCS sollte optimalerweise ein Produkt darstellen, woran unabhängig von anderen Produkten gearbeitet werden kann. So kann ein Team an Stories für exakt ein SCS arbeiten.

Sind SCSs wirklich immer sinnvoll?

Wie das halt mit allem so ist, finden sich in der Praxis sicherlich auch häufig Umgebungen, in die der SCS-Ansatz nicht ganz passt. Für eine funktionierende SCS-Landschaft innerhalb eines Software-Projektes ist der Schnitt, mit dem das Gesamtsystem in SCSs geschnitten wird, sehr wichtig. Findet sich für die Fachlichkeit, die man umsetzen möchte, kein Schnitt, mit dem Teams wirklich unabhängig arbeiten können, sollte vielleicht eine andere Architektur in Erwägung gezogen werden. Was mich zum nächsten wichtigen Punkt bringt: Unabhängigkeit
Auf der grünen Wiese ist es oft anders als in der Praxis. In der Praxis hat man oftmals beispielsweise betriebliche Anforderungen, die eine theoretische Ausarbeitung zum Thema Self-Contained Systems nicht abdecken kann. Ist es im betroffenen Software-Projekt so, dass für alles außerhalb des Git-Repos eine zentralisierte IT-Abteilung zuständig ist, kann man den SCS-Ansatz noch einmal überdenken, da SCSs schon einiges an Overhead mitbringen. Hat man einen Monolithen, benötigt man alles genau ein mal. Seien es die verschiedenen Staging-Umgebungen, das Installieren von Zertifikaten, Firewall-Freischaltungen, Build-Server, Stash und was alles noch zu tun ist, um eine Anwendung in Produktion zu bekommen. Schneidet man diesen Monolithen in zehn SCSs, verzehnfacht sich beinahe der Aufwand. Wenn jetzt allerdings all diese Abhängigkeiten außerhalb deines Teams liegen, ist es schwer von Agilität zu sprechen und auch die zentralisierte IT-Abteilung wird eventuell zum Flaschenhals. Hier gilt: je mehr devops, desto besser!

Herausforderungen bei der UI-Entwicklung

Jedes SCS wird sein eigenes UI mitbringen. Um trotzdem ein gemeinsames look&feel zu erreichen, müssen einige Schritte getan werden. Für manche Projekte reicht da vielleicht schon ein gemeinsamer Style-Guide, der auch user-experience und usability behandelt. Ohne ein gemeinsames Dokument wäre es nahezu unmöglich, sonst ein gemeinsames look&feel zu entwickeln. Benötigt der Styleguide gewisse assets, müssen alle UIs Zugriff darauf haben. Dies kann entweder über einen Asset-Server geschehen, oder über eine Asset-Pipeline. Dabei werden Assets dann als dependency, genau wie bei jeder anderen Code-Dependency, behandelt. Genau genommen sollten SCSs ja keinen Code teilen, das wäre dann eine Ausnahme dazu, die in Kauf genommen wird. Um ein einheitliches UI zu erreichen, können beispielsweise web components verwendet werden. Für weitere Informationen zu web components, hier entlang: https://www.webcomponents.org/introduction

Generell möchte ich hier festhalten, dass bei der Entwicklung von SCS hier genau geschaut werden muss, wie sich organisatorisch aufgestellt wird. Meiner Meinung nach sollten Teams querschnittlich sein, so dass alle Aufgaben im Team bleiben können, um nicht etwa z.B. ein Frontend-Team zu bilden, welches Frontend für alle SCS-Squads entwickelt.

vs. Microservices

Ja dann sind das doch eigentlich Microservices!!!!!1111

Zugegeben, ein kontrovers diskutiertes Thema. Laut scs-architecture.org sind die wichtigsten Unterschiede:

  • Microservice ist typischerweise kleiner als ein SCS
  • Dadurch in einem System typischerweise weniger SCS als Microservices, um komplette Domäne abzubilden
  • SCSs sollten nicht miteinander kommunizieren, wohingegen das für Microservices kein Problem ist
  • SCSs haben eine UI, wohingegen die UI bei Microservices woanders liegen kann, allerdings nicht muss

Man sieht, dass auch die Autoren/Autorinnen von scs-architecture keine klare Abgrenzung finden, sondern viel mit den Wörtern "should", "might", "probably", "typically" arbeiten. Ich finde, da muss auch garnicht so hartnäckig eine Abgrenzung her, denn der darunter liegende Gedanke der Isolation bleibt der gleiche.

Zusammenfassung

Self-Contained Systems sind also eine Softwarearchitektur, die beschreibt, eine fachliche Domäne in einzelne Systeme zu schneiden, deren Verbund wiederum das Gesamtsystem bildet. SCSs sollten dabei verschiedene Eigenschaften erfüllen, um einen tatsächlichen Mehrwert zu bieten. Es stehen viele Argumente auf der Pro-Seite von SCSs, allerdings sollte meiner Meinung nach genau darauf geschaut werden, wie der theoretische Ansatz von SCSs in das jeweilige Unternehmen getragen werden kann. Denn auch hier gilt, wie bei jeder anderen Technologie: es sollte zu den jeweiligen Anforderungen passen.

Weitere Informationen

Quellen

[1] scs-architecture.org http://scs-architecture.org/index.html
[2] elastic.io https://www.elastic.io/breaking-down-monolith-microservices-and-self-contained-systems/
[3] dev.otto.de https://dev.otto.de/2016/03/20/why-microservices/#more-2320