Kolumne: Stropek as a Service

Simplify Your Life: Einfache Lösungen statt künstlicher Komplexität
Keine Kommentare

Ein Hello-World-Beispiel, das ich für meine Studentinnen und Studenten entwerfe, darf zu Demonstrationszwecken komplexer werden, als es für die Lösung des vorliegenden Problems eigentlich notwendig wäre. In meiner beruflichen Arbeit mit Entwicklungsteams mache ich aber gerade im Kontext von Cloud-Anwendungen das genaue Gegenteil: Ich versuche regelmäßig, unnötige Komplexität aus Projekten herauszunehmen.

Ich tüftle gerne an Softwareproblemen. Meine Abende im Advent verbrachte ich mit den Programmierrätseln von Advent of Code [1]. Ich habe großen Spaß daran, für Vorträge, Artikel oder den Unterricht anspruchsvolle Beispiele und Übungen zu erarbeiten. Da darf dann ein Hello-World-Beispiel zu Demonstrationszwecken komplexer werden, als es für die Lösung des vorliegenden Problems eigentlich notwendig wäre.

In meiner beruflichen Arbeit mit Entwicklungsteams mache ich aber gerade im Kontext von Cloud-Anwendungen das genaue Gegenteil: Ich versuche regelmäßig, unnötige Komplexität aus Projekten herauszunehmen. Jedes Projekt hat eine inhärente Komplexität, die sich unvermeidlich aus der Aufgabenstellung ergibt. Vereinfacht man an dieser Stelle, gibt man den Benutzerinnen und Benutzern nicht das, was sie von der jeweiligen Software erwarten. Als Softwareentwicklerinnen und -entwickler fügen wir aber oft selbst Komplexität hinzu, die nicht unmittelbar die funktionalen Anforderungen der Benutzerinnen und Benutzer widerspiegelt. Plausible Gründe dafür sind beispielsweise:

  • automatisierbare Testbarkeit

  • Aufteilung in lose gekoppelte Module, um in mehreren Teams parallel arbeiten zu können

  • Codewiederverwendung über Projekt- und Teamgrenzen hinweg

  • nichtfunktionale Anforderungen, die organisationsweit vorgegeben oder von uns implizit angenommen werden (z. B. Sicherheitsanforderungen, Performanceanforderungen, Industriestandards)

  • Kompatibilität (z. B. Einsatz bestehender Softwaremodule oder Nutzung gewisser Basiskomponenten wie Betriebssysteme, Datenbanksysteme etc.)

Problematisch wird die Sache dann, wenn man es mit dem künstlichen Hinzufügen von Komplexität übertreibt. Ich unterstelle keinem Projektteam, mit dem ich je gearbeitet habe, das in böser Absicht getan zu haben – ganz im Gegenteil! In bester Absicht versucht man, sich an die vielzitierten Best Practices zu halten, von denen man in Vorträgen gehört oder in Büchern und Artikeln gelesen hat. Tut man das, ohne die Hintergründe für diese Empfehlungen zu berücksichtigen, läuft man Gefahr, dass die angeblichen Best Practices das eigene Projekt in den Untergang treiben.

Diese Kolumne ist ein Plädoyer für die Rückkehr zur Einfachheit, für das Verzichten auf überverkomplizierte Softwarearchitekturen, für das Reduzieren auf jene Entwicklungsprinzipien, die für das jeweilige Projekt und Team wirklich notwendig sind.

Microservices

Ich möchte das Thema künstliche Komplexität anhand von Symptomen erläutern, und das erste Symptom ist der übertriebene Einsatz von Microservices. In dieser Kolumne habe ich schon oft über Microservices geschrieben, und die regelmäßigen Leserinnen und Leser wissen daher, dass ich diesem Architekturansatz grundsätzlich positiv gegenüberstehe. Man kann es aber leicht übertreiben. Ein Team mit einer Handvoll Entwicklerinnen und Entwickler sollte die von ihm erstellte Software nicht in dutzende Microservices zerteilen, auch wenn die oft zitierten Vorteile verlockend sind:

  • Microservices können unabhängig voneinander ausgerollt und versioniert werden.

  • Das Zerteilen eines Gesamtsystems erlaubt es, in verschiedenen Bereichen die jeweils richtigen Basiskomponenten einzusetzen. Man kann auch leichter in einzelnen Bereichen neue Technologien ausprobieren.

  • Fehler in einzelnen Microservices reißen nicht zwangsläufig das Gesamtsystem mit in den Abgrund.

  • Microservices werden von den großen Cloud-Anbietern als De-facto-Architekturstandard beworben.

All die oben genannten Vorteile sind richtig, man muss sie aber vor dem Hintergrund der Projektsituationen betrachten, aus denen der Architekturansatz entstanden ist. Riesige Unternehmen mit Teams aus vielen Dutzenden oder Hunderten Entwicklerinnen und Entwicklern sind früher an Softwaremonolithen verzweifelt, weil diese im Lauf der Zeit zu unflexiblen und nicht mehr wartbaren Monstern geworden sind. In solchen Situationen sind meiner Ansicht nach Microservices sinnvoll, insbesondere in Verbindung mit einer Organisationsform, die sich an den Ideen der DevOps-Bewegung orientiert.

Kleine und mittlere Teams sind damit aber oft überfordert und wesentlich besser bedient mit einem oder ganz wenigen gut strukturierten Softwaremonolithen. Bei mir läuten alle Warnglocken, wenn ich in Erstgesprächen sehe, dass die Anzahl der Microservices fast gleich der Anzahl an Teammitgliedern ist oder diese sogar übersteigt. In der Regel lässt sich in solchen Konstellationen die Entwicklungsproduktivität signifikant steigern, wenn aus dem stark verteilten System mit vielen, lose gekoppelten Komponenten ein stärker zentralisiertes gemacht wird.

Microfrontends

Der Trend hin zu lose gekoppelten Modulen im Backend hat vor dem Frontend nicht haltgemacht. Im Moment ist das Thema Aufteilung der Benutzerschnittstelle sogar eines der häufigsten, mit dem ich in Architekturworkshops bei Kunden konfrontiert bin. Ich verstehe das Bedürfnis von Entwicklungsteams nach leicht erweiterbaren Benutzerschnittstellenkomponenten. Mir ist klar, dass das Versprechen, verschiedene UI-Technologien oder Plattformversionen mischen zu können, verlockend ist. Man verspricht sich auf der organisatorischen Seite viel davon, dass jedem Team die Gesamtverantwortung für seinen Themenbereich von Backend (Microservice) bis Frontend (Microfrontend) zugewiesen werden kann.

In der Praxis gilt aber das oben Gesagte für Microservices. Nicht selten komme ich zu Teams, in denen zwei oder drei Frontend-Entwicklerinnen und -entwickler einer viel größeren Zahl an Personen gegenüberstehen, die für das Backend verantwortlich sind. In solchen Zusammenstellungen kommt leicht der Gedanke auf, den Microservices-Ansatz bis zum Frontend durchzuziehen. Ich kann nur sagen: Die armen Menschen, die am Frontend entwickeln! Sie müssen ständig zwischen Projekten hin- und herhüpfen. Der Compiler hat wegen der losen Kopplung kaum Möglichkeiten, Inkonsistenzen zwischen UI-Modulen zur Übersetzungszeit aufzuzeigen, und daher müssen komplexe End-to-End-UI-Tests her. Jedes Upgrade des Basisframeworks (z. B. Angular, React) muss für zig Projekte vorgenommen werden.

Meine Bitte ist, dass man auch im Frontend die Verwendung unabhängiger Module auf ein Minimum reduziert, das die im Projekt vorliegenden Anforderungen bewältigen kann und das von der gegebenen Größe des Frontend-Entwicklungsteams zu verkraften ist.

Netzwerksicherheit

Nicht zuletzt wegen Entwicklungen rund um die Covid-19-Krise kommen in den letzten Monaten mehr und mehr mittelständische und größere Unternehmen auf mich zu, in denen eine Abkehr von einer strikten No-Cloud-Strategie stattgefunden hat. In Sachen Netzwerksicherheit haben die meisten dieser Organisationen eine lange zurückreichende Historie, die durch einen Fokus auf Perimetersecurity geprägt ist. Rund um das Firmennetzwerk werden große, virtuelle Mauern in Form von Firewalls, DMZs, Proxies etc. errichtet, damit mögliche Angreifer aus dem großen, bösen Internet draußen gehalten werden. Innerhalb des Firmennetzwerks sind alle Freunde und daher gelten hier weniger strenge Sicherheitsmaßnahmen.

Beim Weg in die Cloud nehmen solche Organisationen ihr bestehendes Wissen mit und wollen nach den gleichen Prinzipien und Regeln Softwaresysteme bauen. Wieder unterstelle ich keine böse Absicht, stelle jedoch fest, dass dadurch das Gegenteil von dem erreicht wird, was man beabsichtigt: Cloud-Lösungen werden unsicherer. Der Grund ist, dass es in der Cloud insbesondere durch PaaS- und Serverless-Technologien Möglichkeiten gibt, die im Firmennetzwerk früher nicht vorhanden waren. Hier einige Beispiele:

  • hochsichere Verwaltung von Secrets

  • automatisches Zertifikatsmanagement

  • automatisiertes Identity-Management für Machine-to-Machine-Kommunikation (in Azure als Managed Identities bekannt)

  • einfach zu integrierende und kostengünstige Logging- und Telemetrielösungen

  • Machine-Learning-Systeme zur Verhinderung von Angriffen durch Erkennung von Nutzungsanomalien

  • Fertige, hochsichere Services für Datenbanken, Storage, Message Broker und vieles mehr

Wer versteht, wie man solche Dienste richtig einsetzt und kombiniert, kann in vielen Systemen auf Perimetersecurity teilweise oder komplett verzichten, ohne dadurch fahrlässig zu sein. Das Internet wird zum Unternehmensnetzwerk und die Komplexität der Cloud-Lösung nimmt spürbar ab. Wer allerdings auf die Einhaltung überholter Richtlinien aus der Zeit ohne Cloud-Computing pocht, verhindert nicht selten den Einsatz moderner PaaS- und Serverless-Cloud-Dienste. Das wirkt sich negativ auf die Entwicklungsproduktivität, die laufenden Betriebskosten und gesamtheitlich gesehen auch auf die Sicherheit der Softwarelösung in der Cloud aus.

Kritisch denken

Es ist unsere Aufgabe als Entwicklungsprofis, bestehende Unternehmensrichtlinien, gewachsene Lösungsansätze aus unseren Organisationen und Best Practices aus unserer Industrie kritisch zu hinterfragen und darauf abzuklopfen, ob sie im konkreten Projekt unter den gegebenen Rahmenbedingungen hinsichtlich Teamgröße und Cloud-Umgebung sinnvoll anwendbar sind. Unser Ziel sollte sein, einem Projekt so wenig wie möglich zusätzliche Komplexität hinzuzufügen, die sich nicht von Natur aus von den Anforderungen unserer Benutzerinnen und Benutzer ableiten lässt.

Bitte verstehen Sie diesen Hinweis nicht falsch. Ich plädiere nicht für naives, rein featuregetriebenes Softwaredesign. Meine Warnung bezieht sich auf die Erschaffung technischer Strukturen um ihrer selbst willen und darauf, dass wir uns als Technikerinnen und Techniker nicht selten auf fiktive, zukünftige Entwicklungen vorbereiten wollen, die möglicherweise nie oder zumindest wahrscheinlich nicht so eintreten werden, wie wir heute glauben.

Managerinnen und Managern kommt indirekt eine wesentliche Rolle bei der Vereinfachung von Softwarearchitekturen zu. Nur eine Kultur, in der das Hinterfragen bestehender Richtlinien und ausgetretener Pfade ohne Angst möglich ist, wird zu schlanken und effizienten technischen Lösungsansätzen führen. Das hat schon Melvin Conway 1967 in seiner Aussage treffend zusammengefasst, die man als Conway’s Law kennt und die meiner Erfahrung nach heute im Cloud-Umfeld zutreffender denn je ist: „Any organization that designs a system […] will produce a design whose structure is a copy of the organization’s communication structure“ [2]

Unsere Redaktion empfiehlt:

Relevante Beiträge

Abonnieren
Benachrichtige mich bei
guest
0 Comments
Inline Feedbacks
View all comments
X
- Gib Deinen Standort ein -
- or -