Feature Flags sind nicht die einzige Release-Kontrolle, die Sie brauchen
Ein Team, mit dem ich einmal gearbeitet habe, hat drei Monate lang einen neuen Checkout-Flow gebaut. Der Code war fertig, in Staging getestet und hinter einem Feature Flag in den Hauptbranch gemerged. Als sie das Flag schließlich für 5 % der Nutzer aktivierten, lieferte der Zahlungsanbieter Fehler, die sie in Staging nie gesehen hatten. Das Flag erlaubte es ihnen, die Funktion in Sekunden wieder zu deaktivieren. Aber die eigentliche Frage war: Hätte dieser Code überhaupt in Produktion sein sollen?
Feature Flags sind mächtig. Sie ermöglichen es, Code auszuliefern, der noch nicht aktiv ist, in Produktion mit echtem Traffic zu testen und Änderungen schrittweise auszurollen. Aber sie sind keine universelle Lösung. Manchmal ist ein Branch besser. Manchmal ergibt eine separate Umgebung mehr Sinn. Und manchmal braucht man alle drei zusammen.
Die erste Frage, die es zu beantworten gilt, ist: Was wollen Sie eigentlich erreichen, indem Sie den Zugriff auf eine neue Funktion verzögern oder einschränken?
Wann man einen Branch verwendet
Branches dienen dazu, laufende Arbeiten zu isolieren. Wenn eine Funktion nicht fertig ist und nicht ohne die Anwendung zu beschädigen ausgeführt werden kann, lassen Sie sie in einem Branch. Der Code bleibt vollständig außerhalb des Hauptbranches. Niemand deployed ihn versehentlich. Niemand muss sich daran erinnern, dass ein Flag existiert.
Dies ist die einfachste Form der Kontrolle. Sie funktioniert gut für Funktionen, die noch entwickelt werden, besonders wenn mehrere Entwickler an verschiedenen Teilen arbeiten. Der Hauptbranch bleibt sauber. Das Team merged nur, wenn die Funktion vollständig und reviewed ist.
Aber Branches haben eine Grenze. Sobald der Code gemerged ist, verlieren Sie die Fähigkeit, seine Aktivierung zu steuern. Die Funktion ist entweder im Hauptbranch oder nicht. Es gibt keinen Mittelweg. Hier kommen Feature Flags ins Spiel.
Wann man ein Feature Flag verwendet
Feature Flags steuern das Verhalten, nachdem der Code gemerged wurde. Der Code ist im Hauptbranch, er ist in Produktion deployed, aber er ist nicht für alle Nutzer aktiv. Sie können ihn für einen kleinen Prozentsatz, für interne Tester oder für bestimmte Bedingungen aktivieren.
Dies ist nützlich, wenn die Funktion funktional vollständig ist, Sie sie aber noch nicht allen zeigen möchten. Vielleicht möchten Sie die Stabilität unter echtem Traffic validieren. Vielleicht müssen Sie Fehlerraten vor einem vollständigen Rollout überwachen. Vielleicht möchten Sie eine schrittweise Hochskalierung über mehrere Tage durchführen.
Feature Flags helfen auch beim Rollback. Wenn etwas schiefgeht, schalten Sie das Flag aus, anstatt das Deployment zurückzusetzen. Das ist schneller und sicherer als ein Code-Rollback, besonders wenn das Deployment Datenbankmigrationen oder andere irreversible Änderungen enthält.
Aber Feature Flags sind nicht kostenlos. Sie erhöhen die Komplexität der Codebasis. Jedes Flag ist ein if-else-Zweig, der gewartet, getestet und schließlich entfernt werden muss. Zu viele Flags, die zu lange bestehen bleiben, erzeugen technische Schulden. Teams, die Hunderte von veralteten Flags ansammeln, haben am Ende Code, der schwer zu lesen und noch schwerer zu debuggen ist.
Wann man eine separate Umgebung verwendet
Eine Staging-Umgebung bietet einen Ort zum Testen vor der Produktion. Sie ist von echten Nutzern isoliert. Sie können Integrationstests, manuelle QA und explorative Tests durchführen, ohne jemanden zu beeinträchtigen.
Das Problem ist, dass Staging niemals identisch mit der Produktion ist. Traffic-Muster sind anders. Datenmengen sind kleiner. Echtes Nutzerverhalten kann nicht repliziert werden. Einige Probleme treten nur unter Produktionslast, mit Produktionsdaten oder mit der genauen Infrastrukturkonfiguration auf, die Staging nicht hat.
Deshalb ergänzen sich Feature Flags und Umgebungen. Nutzen Sie Staging für frühe Tests. Nutzen Sie Feature Flags für die Produktionsvalidierung. Sie sind kein Ersatz, sondern zwei Sicherheitsebenen.
Eine große Funktion, die einen Kernablauf ändert – wie das Ersetzen eines Zahlungssystems oder das Neugestalten der Login-Seite – sollte wahrscheinlich zuerst durch Staging gehen. Sobald sie dort besteht, können Sie sie hinter einem Flag in Produktion deployen und die Exposition schrittweise erhöhen.
Kombination von Branch, Umgebung und Flag
In der Praxis verwenden viele Teams alle drei zusammen. Hier ist ein gängiges Muster:
- Arbeiten Sie an einer großen Funktion in einem separaten Branch.
- Mergen Sie den Branch in den Hauptbranch mit deaktiviertem Flag.
- Deployen Sie nach Staging, testen Sie die Funktion, indem Sie das Flag in Staging aktivieren.
- Deployen Sie in Produktion mit noch deaktiviertem Flag.
- Aktivieren Sie das Flag für interne Nutzer oder einen kleinen Prozentsatz.
- Erhöhen Sie den Prozentsatz schrittweise basierend auf dem Monitoring.
- Entfernen Sie das Flag, sobald die Funktion vollständig ausgerollt und stabil ist.
Dieses Muster ist in Teams üblich, die trunk-basierte Entwicklung praktizieren. Der Hauptbranch ist immer deploybar. Große Funktionen werden in kleinere Teile zerlegt, die jeweils von einem Flag gesteuert werden. Das Team merged häufig, deployt oft und verwendet Flags, um zu steuern, was Nutzer sehen.
Wann Feature Flags die falsche Wahl sind
Feature Flags sind nicht immer das beste Werkzeug. Betrachten Sie diese Situationen:
- Die Funktion ist nicht lauffähig. Wenn der Code nicht kompiliert, Tests fehlschlagen lässt oder beim Start abstürzt, mergen Sie ihn nicht. Lassen Sie ihn in einem Branch, bis er funktioniert.
- Die Änderung ist zu groß, um mit einem einzigen Flag gesteuert zu werden. Ein Flag, das ein gesamtes Subsystem umschaltet, ist schwer zu testen und riskant umzulegen. Zerlegen Sie die Funktion in kleinere Teile, jedes mit eigenem Flag, oder verwenden Sie eine Umgebung für die erste Validierung.
- Das Team verwendet Flags, um Entscheidungen zu vermeiden. Wenn ein Flag existiert, weil niemand entscheiden möchte, ob die Funktion bereit ist, ist das ein Prozessproblem, kein Werkzeugproblem. Flags sollten schnelleres Feedback ermöglichen, nicht schwierige Gespräche verzögern.
- Das Flag wird für immer bleiben. Manche Teams behalten Flags auf unbestimmte Zeit, weil das Entfernen riskant erscheint. Das ist ein Zeichen dafür, dass das Flag schlecht entworfen wurde oder dass das Team kein Vertrauen in seinen Release-Prozess hat. Jedes Flag sollte ein geplantes Entfernungsdatum haben.
Eine praktische Checkliste zur Auswahl der Release-Kontrolle
| Situation | Empfohlene Kontrolle |
|---|---|
| Funktion ist unvollständig und kann nicht ausgeführt werden | Branch |
| Funktion ist vollständig, benötigt aber Produktionsvalidierung | Feature Flag |
| Funktion benötigt isolierte Tests vor der Produktion | Staging-Umgebung |
| Funktion ist groß und ändert Kernverhalten | Zuerst Staging, dann Flag |
| Team praktiziert trunk-basierte Entwicklung | Branch + Flag-Kombination |
| Funktion ist klein und risikoarm | Feature Flag oder direktes Deployment |
Dies ist keine starre Tabelle. Jedes Team hat eine andere Risikotoleranz und Infrastruktur. Nutzen Sie sie als Ausgangspunkt für Diskussionen, nicht als Regelwerk.
Der Entscheidungsbaum unten fasst die wichtigsten Fragen und empfohlenen Kontrollen zusammen.
Das eigentliche Ziel
Feature Flags, Branches und Umgebungen sind Werkzeuge. Das Ziel ist nicht, sie alle zu verwenden. Das Ziel ist, Software sicher auszuliefern und schnell Feedback zu bekommen.
Eine gute Release-Strategie ermöglicht es Ihnen, oft zu deployen, in Produktion mit kontrolliertem Risiko zu testen und Dinge auszuschalten, wenn etwas schiefgeht. Sie erlaubt es Ihnen nicht, Entscheidungen aufzuschieben oder halbfertige Funktionen in Produktion anzuhäufen.
Beginnen Sie damit zu verstehen, was Sie kontrollieren wollen. Wählen Sie dann das passende Werkzeug. Und wenn Sie ein Feature Flag verwenden, denken Sie daran, es zu entfernen. Das beste Flag ist das, das nicht mehr existiert.