Die Evolution skalierbarer Web-Anwendungen Eine Analyse der „12 Factor App“-Methodologie

Ein Gastbeitrag von Dennis Hering * Lesedauer: 11 min |

Anbieter zum Thema

In der Softwareentwicklung ist die von Heroku erdachte „12 Factor App“-eine Methodologie für zuverlässige und skalierbare SaaS-Anwendungen. Hier untersuchen wir, wie das Einhalten der Faktoren für performante, zuverlässige und zukunftsfähige Webanwendungen sorgt.

Prinzipien der „12 Factor App“-Methodologie.
Prinzipien der „12 Factor App“-Methodologie.
(Bild: adesso SE)

Die Notwendigkeit, Anwendungen zu entwickeln, die sowohl robust als auch anpassungsfähig sind, ist in der dynamischen Welt der Softwareentwicklung von entscheidender Bedeutung. Eine entscheidende Rolle spielt dabei die Fähigkeit, in verschiedenen Umgebungen mit unterschiedlicher Auslastung effizient zu arbeiten. Dies hat dazu geführt, dass verschiedene Paradigmen und Best Practices eingeführt wurden, von denen sich die 12-Faktor-App-Methodologie als der maßgebliche Leitfaden herauskristallisiert hat.

Diese Methodik haben erfahrenen Developer hinter der Cloud-Plattform Heroku erdacht. Die Methodologie wurde mit einem Fokus auf Software-as-a-Service- kurz SaaS-Anwendungen entwickelt und bietet eine solide Grundlage für die Entwicklung, den Einsatz und die Skalierung von modernen Web-Anwendungen. Das Ziel dieses Artikels ist es, die zentralen Prinzipien der 12-Faktoren-Methodologie im Detail zu untersuchen und ihre Bedeutung in der heutigen Software-Entwicklung zu beleuchten.

1. Faktor: Eine Codebase, viele Deployments

Nach der 12-Faktor-App-Methodologie meint „Codebase“ die zentrale Quellcode-Verwaltung einer Anwendung. Daher gilt das Prinzip, dass es genau eine Code-Basis pro Anwendung geben sollte, aus der allerdings zahlreiche Deployments in verschiedenen Umgebungen (wie Produktion, Staging und Entwicklung) hervorgehen können. Diese Philosophie baut auf dem Prinzip der Konsistenz und Integrität auf, indem sie sicherstellt, dass jeder Deployment-Code identisch und nachvollziehbar ist.

Ein einheitlicher Quellcode sorgt für Konsistenz. Dies erleichtert die Fehlersuche, da in allen Umgebungen derselbe Quellcode verwendet wird. Auch die Nachvollziehbarkeit von Änderungen und Modifikationen wird durch diesen zentralen Ansatz unterstützt. In einem schnelllebigen Entwicklungszyklus, in dem ständig Änderungen vorgenommen werden, bietet eine einheitliche Codebasis Struktur und Klarheit.

Die Codebasis ist von entscheidender Bedeutung. Sie trägt nicht nur zur Qualität und Zuverlässigkeit des Endprodukts bei, sondern optimiert auch die Effizienz des Entwicklungs- und Bereitstellungsprozesses. Letztlich ist sie ein grundlegendes Element jedes Softwareprojekts, das nach den bewährten Methoden der 12-Faktoren-Methodologie entwickelt wird und kann durch eine Versionsverwaltung wie Git erreicht werden.

2. Faktor: Abhängigkeiten deklarieren und isolieren

„Abhängigkeiten“ sind ein weiteres zentrales Element der 12-Faktoren-Methodologie und beziehen sich auf externe Bibliotheken und Frameworks, die eine Anwendung benötigt, um korrekt zu funktionieren. Die Grundidee besteht darin, diese Abhängigkeiten explizit zu deklarieren und zu isolieren.

Das Grundprinzip betont, dass alle benötigten Bibliotheken und Frameworks im Projekt klar spezifiziert werden. Dies bedeutet, dass sie in einer bestimmten Datei oder einem Konfigurationsabschnitt aufgelistet werden. Oft werden auch genaue Versionen angegeben. Ein gutes Beispiel hierfür ist die „package.json“-Datei in Node.js-Projekten oder die „requirements.txt“-Datei in Python-Projekten.

Für die Portabilität und Reproduzierbarkeit von Anwendungen ist die strikte Trennung von Abhängigkeiten daher von großer Bedeutung. Durch die klare Deklaration und Isolierung von Abhängigkeiten können Entwicklerinnen und Entwickler sicherstellen, dass die Anwendung in jeder Umgebung gleich funktioniert, unabhängig davon, ob es sich um einen lokalen Entwicklungsrechner oder einen Produktionsserver handelt.

Dies vermeidet Probleme, die durch unterschiedliche Umgebungen entstehen können, und erleichtert die Einarbeitung neuer Entwicklerinnen und Entwickler. Eine klare Abhängigkeitsdeklaration führt zu konsistenten, fehlerfreien und vorhersagbaren Anwendungsbereitstellungen.

3. Faktor: Konfiguration als Umgebungsvariablen

Der Faktor „Konfiguration“ in der 12-Faktoren-Methodologie befasst sich mit der Art und Weise, wie Anwendungen ihre Umgebungsvariablen handhaben und charakterisieren sollten. „Konfiguriere über die Umgebung und nicht über den Code“ ist das zentrale Dogma.

In den Grundprinzipien dieses Faktors wird betont, dass alle Konfigurationsinformationen, wie zum Beispiel Datenbank-URLs, API-Schlüssel oder externe Service-Adressen, vom Code getrennt gehalten werden sollten. Sie sollten nicht im Quellcode verankert sein, sondern in Umgebungsvariablen gespeichert werden, die je nach Umgebung (Entwicklung, Produktion, Test etc.) unterschiedlich sein können.

Jetzt Newsletter abonnieren

Täglich die wichtigsten Infos zu Softwareentwicklung und DevOps

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

Umgebungsvariablen und Code getrennt zu halten, bietet verschiedene Vorteile. Zum einen werden dadurch vertrauliche Daten geschützt und eine versehentliche Weitergabe (zum Beispiel über ein öffentliches Repository) verhindert. Zum anderen kommt dies der Skalierbarkeit und Portabilität von Anwendungen zugute. Eine Anwendung kann problemlos in verschiedenen Umgebungen mit unterschiedlichen Konfigurationen laufen, ohne dass der Code geändert werden muss.

Das Ergebnis ist die Gewährleistung der Flexibilität und Sicherheit moderner Anwendungen. Developer können Änderungen vornehmen und Deployments durchführen, während die Integrität und Sicherheit ihrer Anwendungen gewahrt bleibt. Für eine effiziente und sichere Softwareentwicklung ist ein klarer Trennungsansatz unerlässlich.

4. Faktor: Behandlung der Unterstützungsdienste als in Verbindung stehende Ressourcen

In der 12-Faktoren-Methodologie sind „unterstützende Dienste“ für die Anbindung externer Services oder Datenquellen, auf die eine Anwendung zugreift, wie beispielsweise Datenbanken, Message Queues oder Caching-Systeme, von entscheidender Bedeutung.

Wichtig ist, dass diese Dienste als angehängte Ressourcen betrachtet werden sollten. Das bedeutet, dass sie ausgetauscht oder geändert werden können, ohne den Code zu ändern, und dass die Verbindung über Konfigurationsinformationen in Form von Umgebungsvariablen erfolgt. Ein Beispiel hierfür ist der Wechsel von einer lokalen Datenbank während der Entwicklung zu einem hochverfügbaren Cluster in der Produktion, ohne dass der Code angepasst werden muss.

Die Behandlung von unterstützenden Diensten als angehängte Ressourcen ist von großer Bedeutung, da sie maximale Flexibilität und Portabilität der Anwendung gewährleistet. Sie vereinfacht Skalierungsprozesse und erhöht die Robustheit der Anwendung gegenüber Dienst- oder Anbieterwechseln.

Diese Entkopplung ermöglicht es Entwicklern und Entwicklerinnen sowie Betreibenden, potenzielle Störungen oder Wartungsarbeiten an diesen Diensten ohne direkte Auswirkungen auf die Hauptanwendung durchzuführen. Die Robustheit, Anpassbarkeit und Wartbarkeit einer Anwendung wird durch die Unabhängigkeit von bestimmten unterstützenden Diensten erhöht.

5. Faktor: Strikte Trennung von Build, Release und Run

Der Faktor „Build, Release, Run“ der 12-Faktoren-Methodologie betrachtet und behandelt den Lebenszyklus einer Anwendung differenziert, indem er die Phasen des Aufbaus, der Veröffentlichung und des Betriebs klar voneinander trennt.

Build: In diesem Schritt wird der Quellcode eines Commits und seiner Abhängigkeiten kompiliert und ein ausführbares Artefakt erzeugt, das alle notwendigen Abhängigkeiten enthält.

Release: In dieser Phase wird das Build-Artefakt mit der aktuellen Konfiguration für eine spezifische Umgebung kombiniert. Das Build-Artefakt ist nun bereit für die Ausführung und sollte an dieser Stelle nicht mehr verändert werden.

Run: Hier wird das Release tatsächlich in der gewünschten Umgebung zur Laufzeit ausgeführt. Dabei kann es sich zum Beispiel um Entwicklung, Staging oder Produktion handeln.

Ein konsistenter, vorhersehbarer und wiederholbarer Entwicklungsprozess wird durch die klare Trennung der Entwicklungsphasen gewährleistet. Das Ergebnis ist eine Minimierung von Fehlerquellen und eine Erhöhung der Softwarequalität. Darüber hinaus unterstützt dieser Faktor die Automatisierung von Deployment-Prozessen sowie die Umsetzung von Continuous Integration und Continuous Deployment.

Durch die klare Definition und Isolation jeder Phase können Entwickler und Betriebsteams sicherstellen, dass Änderungen ohne unerwartete Nebeneffekte und mit minimalen manuellen Eingriffen bereitgestellt werden. Auf diese Weise wird ein zuverlässiger und effizienter Betrieb der Anwendung ermöglicht.

6. Faktor: Die Software als einen oder mehrere Prozesse ausführen

In der Methodologie der 12-Faktor-App-Methodologie bezieht sich der Begriff „Prozesse“ auf die Art und Weise, wie Anwendungen als unabhängige Einheiten in der Ausführungsumgebung ausgeführt werden.

Das Grundprinzip besteht darin, dass diese Prozesse keine Zustände speichern sollen, sondern „stateless“ sein sollten. Jeder benötigte Zustand sollte in einem externen Dienst, zum Beispiel einer Datenbank, gespeichert werden und nicht in einem temporären Zustand innerhalb des Prozesses selbst. Jeder Server oder jede laufende Instanz der Anwendung sollte als eigenständiger und unabhängiger Prozess betrachtet werden, der ausschließlich über Backing-Services mit anderen Prozessen interagiert.

Skalierbarkeit und Robustheit sind die Vorteile dieses Ansatzes. Zustandslose Prozesse ermöglichen eine horizontale Skalierung, bei der bei steigender Last einfach weitere Instanzen der Anwendung hinzugefügt werden können, ohne dass der Code geändert werden muss. Sie erhöhen auch die Ausfallsicherheit, da ein ausgefallener Prozess einfach durch einen anderen ersetzt werden kann.

Darüber hinaus vereinfachen sie die Systemarchitektur, da keine komplexen Mechanismen für den Zustandsaustausch zwischen Prozessen erforderlich sind. Durch die Entfernung des Zustands aus der Anwendung ermöglichen sie einen flexiblen, robusten und leicht skalierbaren Betrieb, der für moderne Cloud-native Anwendungen unerlässlich ist.

7. Faktor: Dienste durch Port Bindung exportieren

Die 12-Faktoren-Methodologie befasst sich mit der Art und Weise, wie Anwendungen mit dem Netzwerk kommunizieren, und der Faktor „Port Binding“ als Methodik bezieht sich auf die konkrete Implementierung.

Dieses Prinzip erfordert, dass eine 12-Faktoren-Anwendung als eigenständiger Dienst agiert, indem sie an einem bestimmten Port gebunden ist. Dies steht im Gegensatz zu herkömmlichen Ansätzen, bei denen Anwendungen oft hinter einem Webserver platziert werden und nicht direkt an einen Port gebunden sind. Lediglich der Webserver hat in diesem Szenario feste Bindungspunkte in Form von Portnummern.

Der Vorteil dieses Ansatzes ist zum einen die Unabhängigkeit der Anwendung. Eine 12-Fackor-Applikation integriert ihren eigenen Webserver und ist somit nicht von einem externen abhängig. Sie kann somit in jeder Umgebung ausgeführt werden, die Netzwerkkommunikation unterstützt. Dies erleichtert den Einsatz und die Skalierung. Zum anderen ermöglicht dieser Ansatz, da jeder Dienst auf einem definierten Port gebunden ist und leicht adressierbar ist, eine klare und eindeutige Kommunikation zwischen den Diensten in einer Microservice-Architektur.

Die direkte Portbindung fördert darüber hinaus die Transparenz und Debug-Fähigkeit, da der Datenverkehr direkt durch die Anwendung und nicht durch zwischengeschaltete Proxy- oder Webserver gefiltert wird. Alles in allem verbessert Port Binding die Integrität, die Skalierbarkeit und die Sichtbarkeit von modernen Anwendungen.

8. Faktor: Nebenläufigkeit und Skalierung

Der Faktor „Nebenläufigkeit“ in der 12-Faktor-App-Methodologie bezieht sich auf die Fähigkeit einer Anwendung, mehrere Prozesse parallel auszuführen, um eine höhere Last oder mehr Aufgaben zu bewältigen.

Das Grundprinzip dieses Faktors ist die Skalierbarkeit durch Parallelisierung. Anstatt alle Anfragen oder Aufgaben von einer einzigen Instanz der Anwendung bearbeiten zu lassen, sollten Anwendungen so konzipiert werden, dass sie durch einfaches Hinzufügen weiterer Prozesse skaliert werden können. Dies kann horizontal durch Verteilung der Anwendung auf mehrere Maschinen oder vertikal innerhalb derselben Maschine geschehen.

Der Vorteil dieses Ansatzes ist, dass Anwendungen effizient auf unterschiedliche Lastbedingungen reagieren können. Steigen beispielsweise die Benutzeranfragen plötzlich an, können zusätzliche Prozesse gestartet werden, um die zusätzliche Last zu bewältigen. Dies erhöht auch die Ausfallsicherheit: Fällt ein Prozess aus, können andere weiterarbeiten.

Die horizontale Skalierung ermöglicht außerdem die Nutzung von Cloud-Ressourcen, wodurch Anwendungen einfacher und kostengünstiger skaliert werden können. Für die Entwicklung moderner, zuverlässiger und reaktionsschneller Anwendungen ist dieser Ansatz des Nebenläufigkeitsmanagements daher entscheidend.

9. Faktor: Wegwerfcharakter

Der Faktor „Disposability“ in der 12-Faktoren-Methodologie konzentriert sich darauf, dass Anwendungen jederzeit ohne Vorwarnung und ohne negative Auswirkungen gestartet oder gestoppt werden können, sei es für Skalierungsoperationen, Deployments oder im Falle eines Ausfalls und der Wiederherstellung. Anwendungsinstanzen sollten kurzlebig und austauschbar sein, so das Credo.

Agilität ist ein wesentlicher Vorteil. Anwendungen, die schnell starten, ermöglichen eine elastische Skalierung, wodurch Systemressourcen effizienter genutzt und Lasten schnell verteilt werden können. Schnelles Herunterfahren ist auch ein Garant für reibungslose Wartungs- oder Aktualisierungsprozesse ohne Beeinträchtigung der Benutzererfahrung.

Der Wegwerfcharakter trägt außerdem zur Resilienz bei: Im Fehlerfall lässt sich eine defekte Instanz einfach ersetzen, ohne den Gesamtprozess zu stören. Zudem ermöglicht dieser Ansatz Continuous Deployment und Continuous Integration, so dass neue Versionen der Anwendung nahtlos und ohne Ausfallzeiten ausgerollt werden können. Disposability ist somit eine wesentliche Voraussetzung, um moderne Anwendungen effizient, zuverlässig und mit minimalem manuellem Aufwand zu betreiben.

10. Faktor: Dev/Prod-Parität

Der Faktor „Dev/Prod-Parität“ innerhalb der 12-Faktoren-Methodologie betont die Wichtigkeit, die Entwicklungs-, Test- und Produktionsumgebungen aufeinander abzustimmen.

Die Unterschiede zwischen diesen Umgebungen so gering wie möglich zu halten, ist das Grundprinzip der Dev/Prod-Parität. Dies bezieht sich sowohl auf die Software (Betriebssystem, Datenbank, Server) als auch auf den zeitlichen Abstand zwischen der Entwicklung und der Produktion (Deployment-Zyklus) sowie auf die verwendeten Daten.

Jedoch stellt sich die Frage, warum dieser Ansatz so wichtig ist. Historisch bedingt gab es bisher oft große Unterschiede zwischen Entwicklungs- und Produktionsumgebungen. Diese Unterschiede führten oft zu dem berüchtigten Syndrom, wenn die Software in der Produktion nicht mehr funktionierte: „Auf meiner Maschine hat es funktioniert“.

Eine hohe Dev/Prod-Parität minimiert jedoch diese Unterschiede zwischen den Umgebungen und verringert damit das Risiko fehlerhafter Deployments. Dies wird durch zuverlässigere Software-Releases und kürzere Entwicklungszyklen erreicht. Außerdem wird die Einführung neuer Funktionen oder die Behebung von Fehlern beschleunigt, da die Entwickler und Entwicklerinnen in einer Umgebung arbeiten, die der Produktionsumgebung sehr ähnlich ist. Dev/Prod-Parität ist eine wesentliche Verbesserung der Qualität, Zuverlässigkeit und Geschwindigkeit der Softwareentwicklung.

11. Faktor: Logs

Der Faktor „Logs“ in der 12-Faktoren-Methodologie befasst sich mit der Art, Anwendungsprotokolle zu handhaben und zu verwalten. Grundprinzip dieses Faktors ist, dass Anwendungen keine eigenen Logdateien verwalten oder speichern. Stattdessen sollten sie ihre Ereignisströme, das heißt ihre Protokolle, als kontinuierlichen Ereignisstrom auf die Standardausgabe (stdout) ausgeben.

Dieser Stream kann dann von der laufenden Umgebung erfasst und weiterverarbeitet werden, sei es um zu überwachen, zu archivieren oder zu analysieren. Dadurch, dass Anwendungen ihre Logs nicht selbst verwalten müssen, werden sie von dieser Verantwortung entlastet. Sie können sich auf ihre Kernfunktionen konzentrieren. Darüber hinaus bietet es Flexibilität: Entwickler und Entwicklerinnen sowie Systemadministratoren können die Ausgabe an verschiedene Systeme und Dienste weiterleiten, je nachdem, wie diese Ausgabe benötigen.

Dies ist vor allem in Cloud-Umgebungen von Vorteil. Hier sind dynamische Ressourcen und Skalierbarkeit von Bedeutung. Da Probleme in Echtzeit überwacht und analysiert werden können, ermöglicht dieser Ansatz auch eine einfachere und effizientere Fehlerbehebung. Insgesamt tragen Logs zur Verbesserung der Sichtbarkeit von Anwendungsfunktionen, zur schnellen Erkennung von Betriebsproblemen und zur Gewährleistung der Stabilität des Systems insgesamt bei.

12. Faktor: Admin-Prozesse

Der Faktor „Admin-Prozesse“ der 12-Faktoren-Methodologie für Anwendungen befasst sich mit einmaligen oder gelegentlichen Aufgaben, die im Kontext einer Anwendung ausgeführt werden.

Das Grundprinzip ist, dass diese Aufgaben als einmalige Prozesse behandelt werden sollten, die in derselben Umgebung laufen wie der reguläre, langfristige Prozess der Anwendung. Dies bedeutet, dass sie die gleiche Codebasis und die gleichen Konfigurationen verwenden. Sie laufen jedoch als separate Instanzen und können so eigenständig verwaltet werden.

Die Verwendung der gleichen Umgebung und Codebasis stellt sicher, dass die Administration exakt auf dem gleichen Stand ist wie die eigentliche Applikation. Mögliche Diskrepanzen oder Überraschungen, die bei der Verwendung unterschiedlicher Umgebungen auftreten könnten, werden auf diese Weise vermieden. Zum anderen macht es das Leben für die Entwickler und Entwicklerinnen leichter. Sie können den Hauptcode der Anwendung verwenden, anstatt separate Skripte oder Tools für Verwaltungsaufgaben zu erstellen und zu verwalten. Und schließlich wird durch diesen Ansatz die Nachvollziehbarkeit verbessert.

Da die Admin-Prozesse denselben Protokollierungs- und Überwachungsmechanismen folgen, können wie die Hauptanwendung, wird die Überwachung und Analyse ihrer Ausführung einfacher. Insgesamt ermöglicht Admin-Prozesse eine konsistente, zuverlässige und leicht verwaltbare Abwicklung einmaliger oder gelegentlicher Aufgaben.

Schlussbemerkung

Die Einhaltung dieser 12 Faktoren ist der Schlüssel zur Schaffung von SaaS-Anwendungen, die nicht nur den aktuellen Anforderungen gerecht werden, sondern auch zukunftsfähig sind. Sie legen das Fundament für Performance, Zuverlässigkeit und Skalierbarkeit. Jeder, der ernsthaft über den langfristigen Erfolg seiner SaaS-Initiative nachdenkt, sollte diese Prinzipien beherzigen.

* Über den Autor
Dennis Hering ist Software-Architekt bei adesso SE. Als erfahrener Softwareentwickler besitzt er umfangreiche Expertise in den Bereichen JavaScript/TypeScript, PHP und C#.

Bildquelle: adesso SE

(ID:49776449)