Makrotrends in der Technologiebranche | April 2019
Von
Veröffentlicht: April 24, 2019
Immer wenn wir eine neue Ausgabe des Technologie-Radar veröffentlichen, schaue ich mir dir die aktuellen Entwicklungen in der Softwarebranche an und analysiere Trends, die es nicht den Radar geschafft haben.
Problematisch wird es jedoch, wenn die Benutzerfreundlichkeit eines Tools in einer bestimmten Situation zu einem falschen Paradigma in einem anderen Anwendungsfall führt. Beispielsweise raten wir aktuell von der Verwendung von Jupyter Notebooks zur Entwicklung von Produktivcode ab. Jupyter eignet sich hervorragend, um Daten zu analysieren und daraus Schlussfolgerungen zu ziehen und Einblicke zu gewinnen. Wenn man Jupyter jedoch direkt für Produktivcode verwendet (anstatt den Code in eine für die Produktion geeignetere Programmiersprache wie Python zu portieren), kann dies schnell zu Problemen führen.
Ebenso ist es einfach, eine Datei in einen Amazon S3-Bucket hochzuladen, mit dem Simple Notification Service (SNS) zu verknüpfen und den Inhalt mit einer Lambda-Funktion zu verarbeiten. Allerdings könnte eine solche verworrene Infrastruktur mehr schaden als nutzen.
Dies sind Beispiele für die 80-%-Regel, die in diesem Zusammenhang eine wichtige Rolle spielt. Viele Tools bieten für 80% der Anwendungsfälle eine große Zeitersparnis. Bei den nächsten 10% lassen sich mit dem Tool jedoch nur noch zufriedenstellende Ergebnisse erzielen. Bei den letzten 10% gerät man in eine Sackgasse, aus der man nur mit zusätzlichem Aufwand wieder herauskommt („Pay later“). Wer kann die Komplexität wirklich überschauen und die letzten 10% bewältigen? An diesem Punkt sollten sich Teams besser die Frage stellen, ob sich der Aufwand lohnt oder ein anderes Tool für den Anwendungsfall geeigneter wäre?
Angesichts der wachsenden Beliebtheit von Microservices beobachten wir, dass sie zunehmend mit einem „richtigen“ Servicemanagement betrieben werden. Bestehende Betriebsmethoden wurden unter neuem Namen, wie z. B. „Error budgets“, neu erfunden. Service-Level-Ziele (SLOs) liefern Teams eindeutige Kennzahlen bei der Entscheidung, ob das Konzept „you build it, you run it“ funktioniert. Service Meshes wie Istio unterstützen diese Servicemanagementkonzepte unmittelbar. Oberservability ist in aller Munde, und Teams arbeiten hart daran, dass der Zustand ihrer Systeme für die Überwachungstools angemessen sichtbar ist.
Ein echtes „Betriebsmodell für Microservices“ umfasst auch Änderungen am Aufbau und an den Zuständigkeiten von Teams sowie die damit verbundenen organisatorischen Auswirkungen. Als Grundlage dieser aufkommenden Modelle sollten verschiedene Betriebs- und Plattformfunktionen bestimmt werden. Anschließend sollten erfahrene Teams darauf ausgerichtet werden, zur Bereitstellung dieser Funktionen Produkte zu planen, zu entwickeln und auszuführen. Wir warnen nachdrücklich davor, ein monolithisches „Plattformteam“ aufzustellen oder einfach darauf zu hoffen, dass sich gemeinsame Betriebsfunktionen von allein ergeben werden und sich verbreiten.
Dafür gibt es unzählige Beispiele. Taiko ist eine Node-Bibliothek zur Automatisierung von Chrome, die auf eine klare und schlanke API abzielt. Wir haben zwar schon früher im Browser Tests durchgeführt, aber mit jedem Schritt verbessern wir uns. Deno, eine sichere, serverseitige JavaScript- und TypeScript-Engine, stammt vom Erfinder von Node.js als unmittelbare Reaktion auf die seiner Ansicht nach größten Problembereiche von Node. Gremlin ist eine Sprache für die Suche in Graphen, die gegenüber ihren Vorgängern mit Verbesserungen aufwartet. Immer.js wurde für seine Fortschritte in der Entwicklung der Immutable State Trees mit dem Titel „Breakthrough of the Year“ ausgezeichnet. Micronaut ist ein Framework zur Erstellung von Microservice- und serverlosen Anwendungen, das uns auf diesem Gebiet einen großen Schritt weiterbringt.
Teder Schritt, den wir heute unternehmen, fördert künftige Innovationen, die – wie bereits erwähnt – grundsätzlich unvorhersehbar sind (einem zentralen Grundsatz von Evolutionary Architecture zufolge erstellen wir Systeme in dem Wissen, dass wir diese Veränderungen nicht wirksam voraussagen können).
Kief Morris, der Autor von Infrastructure as Code, sieht das grundlegende Problem darin, dass wir keine klare Grenze zwischen Konfiguration und Logik ziehen. Seiner Ansicht nach sollten wir keine Konfigurationsdateien testen und einen Zielzustand nicht mit programmierbarer Logik definieren. Wer dennoch eines von beidem tut, hat keine klare Unterscheidung zwischen Konfiguration und Logik gemacht.
Er sagt: “Wenn ich etwas deklarieren will, das es noch nicht gibt, dann kann ich die deklarative Sprache um eine neue Definition erweitern und danach die Logik implementieren, ‘wie’ diese Definition umgesetzt wird - und das in einer ordentlichen Programmiersprache mit Tests.”
Neal Ford, indem er bei einem unserer letzten Radar Meetings Dijkstra bewusst falsch zitierte, sagte: “Wir haben die Dinge so sehr voneinander entkoppelt, dass daraus nahezu ein Berg Spaghetti geworden ist, den wir nun wieder zusammensetzen müssen, um etwas Nützliches daraus zu machen.”
Orchestrierung an sich ist keine schlechte Sache, da sie Dinge verbindet. Nur wenn Services flexibel kombiniert werden, kann ein System funktionieren und Mehrwert erzeugen. Ob sich Orchestrierung negativ auswirkt, hängt davon ab, wie verbreitet sie in einer Anwendung und im gesamten System ist.
Genau genommen hat die Businesslogik wohl nur die Aufgabe, Berechnungen vorzunehmen. Allerdings müssen erfolgsrelevante Entscheidungen getroffen werden. Wie sollten wir bei einem bestimmten Skalierungsbedarf vorgehen? Welche Beeinträchtigung ist unter Belastung hinnehmbar? Diese Fragen stellt sich ein Product Owner. Sie sind Teil der Businesslogik, allerdings nicht im traditionellen Sinn. Wir haben uns für den Begriff „Businessverhalten“ entschieden, um Fragen dieser Art abzudecken.
Wir empfehlen den Teams, zunächst einmal anzuerkennen, dass diese Verteilung stattgefunden hat. In einer klassischen Architektur hätte sich alles Wesentliche im Business Domain Layer befunden. Diese Schicht gibt es jedoch nicht mehr, und die entsprechende Logik verteilt sich auf eine Kombination aus Infrastruktur, Konfiguration, Microservices und Integrationen. Ereignisgesteuerte, serverlose Funktionen, Dateien in einem S3-Bucket, der einen Lambda-Dienst auslöst – in einem solchen System lässt sich der Ablauf der Logik nur schwer nachvollziehen. Die Teams sollten nach Möglichkeit Muster verwenden, die das Systemverhalten leichter verständlich machen. Vielleicht sollten sie hierzu sogar die Anzahl der Technologien im System verringern.
Buy now, pay later
In den letzten Jahren haben wir beobachtet, dass zunehmend auf die „Developer Experience“ der Tools und Plattformen Wert gelegt wurde. Dass Entwickler z. B. eine integrierte Entwicklungsumgebung (IDE), Open-Source-Bibliothek oder Cloud-Plattform völlig problemlos nutzen und übernehmen können, gewinnt an Bedeutung. Das ist gut so und oft die treibende Kraft für Innovationen. Entwickler als Kunden eines Produkts zu behandeln, kann durchaus Vorteile bringen.Problematisch wird es jedoch, wenn die Benutzerfreundlichkeit eines Tools in einer bestimmten Situation zu einem falschen Paradigma in einem anderen Anwendungsfall führt. Beispielsweise raten wir aktuell von der Verwendung von Jupyter Notebooks zur Entwicklung von Produktivcode ab. Jupyter eignet sich hervorragend, um Daten zu analysieren und daraus Schlussfolgerungen zu ziehen und Einblicke zu gewinnen. Wenn man Jupyter jedoch direkt für Produktivcode verwendet (anstatt den Code in eine für die Produktion geeignetere Programmiersprache wie Python zu portieren), kann dies schnell zu Problemen führen.
Ebenso ist es einfach, eine Datei in einen Amazon S3-Bucket hochzuladen, mit dem Simple Notification Service (SNS) zu verknüpfen und den Inhalt mit einer Lambda-Funktion zu verarbeiten. Allerdings könnte eine solche verworrene Infrastruktur mehr schaden als nutzen.
Dies sind Beispiele für die 80-%-Regel, die in diesem Zusammenhang eine wichtige Rolle spielt. Viele Tools bieten für 80% der Anwendungsfälle eine große Zeitersparnis. Bei den nächsten 10% lassen sich mit dem Tool jedoch nur noch zufriedenstellende Ergebnisse erzielen. Bei den letzten 10% gerät man in eine Sackgasse, aus der man nur mit zusätzlichem Aufwand wieder herauskommt („Pay later“). Wer kann die Komplexität wirklich überschauen und die letzten 10% bewältigen? An diesem Punkt sollten sich Teams besser die Frage stellen, ob sich der Aufwand lohnt oder ein anderes Tool für den Anwendungsfall geeigneter wäre?
Das Betriebsmodell der Microservices
Mein ehemaliger Kollege Aaron Erickson beschrieb Microservices als erste wahre „cloud-native“ Architektur und wir denken, dass sie sind durchaus eine vernünftige Wahl für moderne Systeme ist. Teams sollten jedoch eine übertriebene Vorliebe für Microservices vermeiden und verstehen, dass Microservices zwar die Entwicklung einfacher gestalten, dafür aber die operative Komplexität erhöhen. Während die Services für sich genommen einfacher sind, ist für das Zusammenspiel dieser Services eine viel komplexere Choreografie erforderlich als bei einer monolithischen Architektur.Angesichts der wachsenden Beliebtheit von Microservices beobachten wir, dass sie zunehmend mit einem „richtigen“ Servicemanagement betrieben werden. Bestehende Betriebsmethoden wurden unter neuem Namen, wie z. B. „Error budgets“, neu erfunden. Service-Level-Ziele (SLOs) liefern Teams eindeutige Kennzahlen bei der Entscheidung, ob das Konzept „you build it, you run it“ funktioniert. Service Meshes wie Istio unterstützen diese Servicemanagementkonzepte unmittelbar. Oberservability ist in aller Munde, und Teams arbeiten hart daran, dass der Zustand ihrer Systeme für die Überwachungstools angemessen sichtbar ist.
Ein echtes „Betriebsmodell für Microservices“ umfasst auch Änderungen am Aufbau und an den Zuständigkeiten von Teams sowie die damit verbundenen organisatorischen Auswirkungen. Als Grundlage dieser aufkommenden Modelle sollten verschiedene Betriebs- und Plattformfunktionen bestimmt werden. Anschließend sollten erfahrene Teams darauf ausgerichtet werden, zur Bereitstellung dieser Funktionen Produkte zu planen, zu entwickeln und auszuführen. Wir warnen nachdrücklich davor, ein monolithisches „Plattformteam“ aufzustellen oder einfach darauf zu hoffen, dass sich gemeinsame Betriebsfunktionen von allein ergeben werden und sich verbreiten.
Kontinuierliche Verbesserung
Im Gegensatz zu „guten“ Technologen zeichnen sich „hervorragende“ Technologen (unabhängig von ihrem Fachgebiet) dadurch aus, dass sie mit der aktuellen Lösung nie zufrieden sind, sondern immer versuchen, es noch besser zu machen. Als Branche verbessern wir unsere bestehenden Entwicklungen kontinuierlich.Dafür gibt es unzählige Beispiele. Taiko ist eine Node-Bibliothek zur Automatisierung von Chrome, die auf eine klare und schlanke API abzielt. Wir haben zwar schon früher im Browser Tests durchgeführt, aber mit jedem Schritt verbessern wir uns. Deno, eine sichere, serverseitige JavaScript- und TypeScript-Engine, stammt vom Erfinder von Node.js als unmittelbare Reaktion auf die seiner Ansicht nach größten Problembereiche von Node. Gremlin ist eine Sprache für die Suche in Graphen, die gegenüber ihren Vorgängern mit Verbesserungen aufwartet. Immer.js wurde für seine Fortschritte in der Entwicklung der Immutable State Trees mit dem Titel „Breakthrough of the Year“ ausgezeichnet. Micronaut ist ein Framework zur Erstellung von Microservice- und serverlosen Anwendungen, das uns auf diesem Gebiet einen großen Schritt weiterbringt.
Teder Schritt, den wir heute unternehmen, fördert künftige Innovationen, die – wie bereits erwähnt – grundsätzlich unvorhersehbar sind (einem zentralen Grundsatz von Evolutionary Architecture zufolge erstellen wir Systeme in dem Wissen, dass wir diese Veränderungen nicht wirksam voraussagen können).
Wir wissen heute nicht, wie sich innerhalb der nächsten zwei Jahren unerbittliche, kleine Verbesserungen zu etwas zusammensetzen werden, das revolutionär sein wird.
Konfiguration zu weit getrieben
Im Rahmen unserer Technology-Radar-Ausgaben haben wir uns intensiv mit dem Problem der „Configuration as code“ und den negativen Auswirkungen beschäftigt, die sich offenbar ergeben, wenn eine einfache Konfigurationssprache immer komplexer wird und man schließlich „Turing-vollständiges XML“ erhält, das schwer zu testen und zu erfassen ist. Dafür gibt es zahlreiche Beispiele, die von Build-Dateien bis hin zu Terraform-Konfigurationsdateien mit Vorlagen reichen. Oft stellen die Teams fest, dass es einfacher ist, testbaren Code in einer Programmiersprache zu schreiben als ein Tool zu verwenden, das wir durch Konfigurationsdateien programmierbar gemacht haben.Kief Morris, der Autor von Infrastructure as Code, sieht das grundlegende Problem darin, dass wir keine klare Grenze zwischen Konfiguration und Logik ziehen. Seiner Ansicht nach sollten wir keine Konfigurationsdateien testen und einen Zielzustand nicht mit programmierbarer Logik definieren. Wer dennoch eines von beidem tut, hat keine klare Unterscheidung zwischen Konfiguration und Logik gemacht.
Er sagt: “Wenn ich etwas deklarieren will, das es noch nicht gibt, dann kann ich die deklarative Sprache um eine neue Definition erweitern und danach die Logik implementieren, ‘wie’ diese Definition umgesetzt wird - und das in einer ordentlichen Programmiersprache mit Tests.”
Zunehmende Komplexität der Orchestrierung
In der Technologielandschaft zeichnet sich als allgemeiner Trend eine zunehmende generelle Komplexität ab. Wir sehen damit verbunden einen steigender Aufwand, die einzelnen Komponenten miteinander zu kombinieren. Luigi ist ein neues Tool im Datenbereich, mit dem sich komplexe Batch-Job-Pipelines erstellen lassen. Mit Apache Airflow kann man Workflows programmatisch erstellen, planen und überwachen. Systeme werden laufend um neue Dinge erweitert: Functions-as-a-Service, Workflows, Python-Prozesse usw.Neal Ford, indem er bei einem unserer letzten Radar Meetings Dijkstra bewusst falsch zitierte, sagte: “Wir haben die Dinge so sehr voneinander entkoppelt, dass daraus nahezu ein Berg Spaghetti geworden ist, den wir nun wieder zusammensetzen müssen, um etwas Nützliches daraus zu machen.”
Orchestrierung an sich ist keine schlechte Sache, da sie Dinge verbindet. Nur wenn Services flexibel kombiniert werden, kann ein System funktionieren und Mehrwert erzeugen. Ob sich Orchestrierung negativ auswirkt, hängt davon ab, wie verbreitet sie in einer Anwendung und im gesamten System ist.
Diffusion der Businesslogik
Probleme durch übertriebene Konfiguration und die Komplexität der Orchestrierung sind Symptome eines größeren Trends: Die Businesslogik ist nicht mehr auf kleine Codeblöcke beschränkt, sondern de facto auf ein ganzes System verteilt. Sie zeigt sich in der Art, wie wir Kubernetes-Pods konfigurieren und unsere Lambda-Funktionen kombinieren. Es gibt die altmodische Vorstellung von einer ‚Workload‘, die sich an verschiedene Orte verschieben lässt. Für das Schreiben und Hosten der Workload sind jeweils Zuständigkeiten festgelegt, und die Steuerungsebene und die Anwendung sind klar voneinander getrennt. Diese Vorstellung trifft heute nicht mehr zu”Genau genommen hat die Businesslogik wohl nur die Aufgabe, Berechnungen vorzunehmen. Allerdings müssen erfolgsrelevante Entscheidungen getroffen werden. Wie sollten wir bei einem bestimmten Skalierungsbedarf vorgehen? Welche Beeinträchtigung ist unter Belastung hinnehmbar? Diese Fragen stellt sich ein Product Owner. Sie sind Teil der Businesslogik, allerdings nicht im traditionellen Sinn. Wir haben uns für den Begriff „Businessverhalten“ entschieden, um Fragen dieser Art abzudecken.
Wir empfehlen den Teams, zunächst einmal anzuerkennen, dass diese Verteilung stattgefunden hat. In einer klassischen Architektur hätte sich alles Wesentliche im Business Domain Layer befunden. Diese Schicht gibt es jedoch nicht mehr, und die entsprechende Logik verteilt sich auf eine Kombination aus Infrastruktur, Konfiguration, Microservices und Integrationen. Ereignisgesteuerte, serverlose Funktionen, Dateien in einem S3-Bucket, der einen Lambda-Dienst auslöst – in einem solchen System lässt sich der Ablauf der Logik nur schwer nachvollziehen. Die Teams sollten nach Möglichkeit Muster verwenden, die das Systemverhalten leichter verständlich machen. Vielleicht sollten sie hierzu sogar die Anzahl der Technologien im System verringern.
Hinweis: Die in diesem Artikel geäußerten Aussagen und Meinungen sind die der Autor:innen und spiegeln nicht zwingend die Position von Thoughtworks wider.