Warum Ihre Deployment-Strategie von der Art der Anwendung abhängt
Wenn Sie zum ersten Mal Software entwickeln, sehen alle Anwendungen ungefähr gleich aus. Sie schreiben Code, führen ihn aus, jemand nutzt ihn. Aber sobald Sie diese Anwendung an einen Ort bringen müssen, an dem echte Benutzer darauf angewiesen sind, stellen Sie schnell fest, dass Anwendungen sehr unterschiedliche Persönlichkeiten haben. Und diese Unterschiede bestimmen alles darüber, wie Sie sie deployen.
Die zustandslose Anwendung: Einfach und austauschbar
Stellen Sie sich eine Wetter-API vor. Sie akzeptiert einen Stadtnamen, gibt Temperatur- und Luftfeuchtigkeitsdaten zurück. Jede Anfrage ist unabhängig. Die Anwendung holt jedes Mal frische Daten, speichert nichts lokal und hat kein Gedächtnis dafür, wer was gefragt hat.
Diese Art von Anwendung wird als zustandslos (stateless) bezeichnet. Sie kümmert sich nicht um vorherige Anfragen. Jeder Aufruf ist ein unbeschriebenes Blatt.
Zustandslose Anwendungen sind am einfachsten zu deployen. Wenn eine neue Version kaputt geht, tauschen Sie sie gegen die alte aus. Keine Daten, um die man sich sorgen müsste, keine Migration, die rückgängig zu machen wäre, keine Kompatibilitätsprobleme. Sie können in Sekunden zurückrollen. Sie können horizontal skalieren, indem Sie weitere Instanzen starten. Sie können Instanzen ohne viel Aufwand beenden.
Das Risiko ist begrenzt. Wenn etwas schiefgeht, beschränkt sich der Schaden auf die Anfragen, die gerade bearbeitet wurden. Niemand verliert Daten. Niemands Sitzung wird beschädigt.
Die zustandsbehaftete Anwendung: Vorsichtig und kompliziert
Stellen Sie sich nun ein Kino-Ticketbuchungssystem vor. Diese Anwendung speichert, welche Plätze belegt sind, wer sie gekauft hat und wie bezahlt wurde. Jede Transaktion ändert den Zustand des Systems. Die Datenbank enthält die Wahrheit, und der Anwendungscode muss mit dieser Wahrheit synchron bleiben.
Dies ist eine zustandsbehaftete (stateful) Anwendung. Sie ist auf persistierte Daten angewiesen. Und das ändert alles am Deployment.
Sie können nicht einfach Versionen austauschen. Wenn die neue Version ändert, wie sie Daten liest oder schreibt, muss möglicherweise zuerst das Datenbankschema migriert werden. Wenn die Migration läuft und der neue Code einen Fehler hat, ist ein Zurückrollen nicht einfach. Der alte Code versteht das neue Schema möglicherweise nicht. Die Daten wurden vielleicht bereits transformiert. Möglicherweise müssen Sie aus einem Backup wiederherstellen, was Zeit kostet und riskiert, aktuelle Transaktionen zu verlieren.
Zustandsbehaftete Anwendungen erfordern eine sorgfältige Abfolge: Migrieren Sie die Datenbank, deployen Sie den neuen Code, verifizieren Sie, dass alles funktioniert, und haben Sie einen Plan für den Fall, dass es nicht funktioniert. Ein Rollback ist selten ein einzelner Befehl. Es ist oft ein mehrstufiger Prozess, der Koordination erfordert.
Das Auswirkungsspektrum: Internes Tool vs. öffentlicher Dienst
Anwendungen unterscheiden sich auch darin, wie viel Schaden sie anrichten können, wenn sie ausfallen.
Betrachten Sie ein internes Admin-Dashboard, das von fünf Personen in Ihrem Unternehmen genutzt wird. Wenn es für zehn Minuten ausfällt, ist vielleicht jemand genervt, aber niemand verliert Geld. Das Deployment kann unkompliziert sein. Sie können sich etwas Ausfallzeit leisten. Sie können Änderungen pushen und Probleme später beheben.
Betrachten Sie nun ein Zahlungs-Gateway oder eine E-Commerce-Checkout-Seite. Tausende von Benutzern greifen jede Sekunde darauf zu. Wenn es ausfällt, scheitern Transaktionen, Benutzer beschweren sich, die Einnahmen sinken. Die Auswirkung ist sofort spürbar und messbar.
Dieser Unterschied in der Auswirkung bestimmt, wie vorsichtig Sie beim Deployment sein müssen. Anwendungen mit geringen Auswirkungen können direkt mit minimalem Aufwand deployed werden. Anwendungen mit hohen Auswirkungen erfordern gestaffelte Rollouts, Monitoring, Feature Flags und einen klaren Rollback-Plan. Sie könnten zuerst auf einen Server deployen, auf Fehler achten und dann den Traffic schrittweise erhöhen. Sie könnten die neue Version eine Zeit lang neben der alten laufen lassen. Sie könnten Canary-Deployments oder Blue-Green-Strategien verwenden.
Das folgende Flussdiagramm hilft Ihnen zu entscheiden, welche Deployment-Strategie zu Ihrer Anwendung und Ihrem Risikoniveau passt:
Der Grad der Prozesse sollte dem Risiko entsprechen. Nicht jede Anwendung braucht eine mehrstündige Deployment-Pipeline mit Genehmigungen und Runbooks. Aber diejenigen, die echten Schaden anrichten können, verdienen diese Aufmerksamkeit.
Abhängigkeiten: Die versteckte Kopplung
Manche Anwendungen sind in sich geschlossen. Sie laufen, ohne etwas anderes zu benötigen. Sie deployen sie, sie funktionieren.
Die meisten Anwendungen sind nicht so. Sie sind abhängig von Datenbanken, externen APIs, Message Queues oder anderen internen Diensten. Eine neue Version Ihrer Anwendung könnte auf einen neuen Endpunkt einer API angewiesen sein, die noch nicht aktualisiert wurde. Sie könnte ein bestimmtes Antwortformat erwarten, das die alte API nicht liefert. Sie könnte eine Datenbankmigration benötigen, die noch nicht ausgeführt wurde.
Abhängigkeiten erzeugen Kopplung. Wenn Sie eine neue Version deployen, müssen Sie sicherstellen, dass alles, wovon sie abhängt, verfügbar und kompatibel ist. Dabei geht es nicht nur um Verfügbarkeit. Es geht um Vertragskompatibilität. Ihr neuer Code könnte isoliert perfekt funktionieren, aber in der Produktion scheitern, weil sich das Datenbankschema geändert hat, die API-Antwort geändert hat oder sich das Nachrichtenformat geändert hat.
Deshalb ist die Reihenfolge des Deployments wichtig. Wenn Ihre Anwendung von einer Datenbank abhängt, kommt die Datenbankmigration normalerweise zuerst. Wenn sie von einem anderen Dienst abhängt, sollte dieser Dienst zuerst deployed werden oder zumindest abwärtskompatibel sein. Wenn Sie die Kompatibilität nicht garantieren können, müssen Sie Ihr Deployment so gestalten, dass sowohl alte als auch neue Versionen gleichzeitig laufen können.
Was das für Ihre CI/CD-Pipeline bedeutet
All diese Unterschiede – zustandslos versus zustandsbehaftet, geringe versus hohe Auswirkungen, unabhängig versus abhängig – prägen, wie Sie Ihre CI/CD-Pipeline aufbauen.
Es gibt keine einzelne Deployment-Strategie, die für jede Anwendung funktioniert. Eine Pipeline, die für einen zustandslosen Microservice entwickelt wurde, wird bei einem zustandsbehafteten Monolithen versagen. Ein Deployment-Prozess, der für ein internes Tool gebaut wurde, wird für ein kundenorientiertes Zahlungssystem zu riskant sein. Ein Rollback-Plan, der für eine eigenständige Anwendung funktioniert, wird bei einer Anwendung, die von einer migrierten Datenbank abhängt, scheitern.
Ihre Pipeline muss die Natur der Anwendung widerspiegeln, die sie bedient. Das bedeutet:
- Zustandslose Anwendungen können einfache Pipelines mit schnellem Rollback verwenden.
- Zustandsbehaftete Anwendungen benötigen sorgfältige Migrationsschritte und getestete Rollback-Prozeduren.
- Anwendungen mit hohen Auswirkungen erfordern gestaffelte Deployments und Monitoring-Gates.
- Abhängige Anwendungen benötigen Kompatibilitätsprüfungen und geordnete Deployments.
Praktische Checkliste zur Bewertung der Deployment-Anforderungen Ihrer Anwendung
Bevor Sie Ihre Deployment-Pipeline entwerfen oder anpassen, gehen Sie diese Checkliste durch:
- Speichert die Anwendung Daten, die Deployments überdauern müssen? Wenn ja, planen Sie Datenbankmigrationen und reversible Schemaänderungen.
- Wie viele Benutzer sind betroffen, wenn die Anwendung ausfällt? Wenn die Anzahl groß oder die finanzielle Auswirkung hoch ist, fügen Sie gestaffelte Rollouts und Monitoring hinzu.
- Hängt die Anwendung von anderen Diensten oder Datenbanken ab? Wenn ja, überprüfen Sie die Kompatibilität und planen Sie die Deployment-Reihenfolge.
- Können Sie durch Austausch der alten Version zurückrollen, oder müssen Sie Datenänderungen rückgängig machen? Wenn Letzteres, testen Sie die Rollback-Prozedur, bevor Sie sie benötigen.
- Kann die Anwendung das gleichzeitige Ausführen zweier Versionen handhaben? Wenn nicht, benötigen Sie möglicherweise Ausfallzeiten oder ein Blue-Green-Deployment-Muster.
Die konkrete Erkenntnis
Die Art und Weise, wie Sie eine Anwendung deployen, wird nicht durch die Programmiersprache, das Framework oder das von Ihnen verwendete Tool bestimmt. Sie wird durch die Natur der Anwendung bestimmt: ob sie Zustand hält, wie viel Schaden ein Fehler verursacht und wovon sie abhängt. Verstehen Sie zuerst diese drei Dinge. Dann entwerfen Sie Ihre Pipeline. Alles andere ist Implementierungsdetail.