Softwareentwicklung: Wann Feature Flags sinnvoll sind - und wann nicht
Dieser Artikel ist eine Übersetzung. Das Original des Softwareentwicklers und Bloggers Rajiv Prabhakar ist hier(öffnet im neuen Fenster) zu finden.
In den vergangenen Jahren habe ich in mehreren Teams gearbeitet, die bei Feature Flags sehr unterschiedliche Strategien verfolgt haben. Ich habe die Vor- und Nachteile all dieser Strategien gesehen und mit der Zeit festgestellt, dass ich weder eine extrem ablehnende noch eine extrem befürwortende Haltung besonders gut finde. Es gibt eine Menge Nuancen bei diesem Thema, und ich denke, es lohnt sich, die verschiedenen Szenarien, in denen Feature Flags sinnvoll sind oder nicht, genauer zu betrachten.
Sinnvolle Anwendungen für Feature Flags
Es gibt einige wichtige Szenarien, in denen Feature Flags sehr sinnvoll sind. Zum einen für A/B-Tests(öffnet im neuen Fenster) , bei denen unterschiedliche Aktionen unterschiedlichen Nutzern zufällig zugewiesen werden. Ich habe gesehen, wie diese Strategie bei Amazon sehr gut eingesetzt wird, indem neue Funktionen durch ein Feature Flag gesteuert werden, das eigentlich von einem internen A/B-Testing-Framework kontrolliert wird. Das Framework wählt einige Amazon-Kunden nach dem Zufallsprinzip für die neue Funktion aus und überwacht dann ihr Verhalten, um die geschäftlichen Auswirkungen abzuschätzen.
Ich war zunächst skeptisch; allerdings überzeugte mich, wie einfach das Framework zu bedienen war und welche wertvollen Erkenntnisse es über die Vor- oder Nachteile bestimmter Funktionen lieferte. Entscheidungen, die sonst auf einem vagen Gefühl gründeten, was gerade funktionieren könnte, basierten nun auf echten Daten. Um neue Funktionen dynamisch umzuschalten, braucht es eben Feature Flags.
Ein weiterer guter Anwendungsfall für Feature Flags ist, wenn Sie an einem sehr komplexen Projekt arbeiten, bei dem viele verschiedene Teilaufgaben in verschiedenen Teilen des Systems erledigt werden müssen – Teilaufgaben, die zu zahlreich und invasiv für einen einzigen Pull Request sind.
In solchen Fällen ist der Versuch, alle Änderungen in Nebenzweigen zu halten und eine gleichzeitige Zusammenführung und Bereitstellung zu koordinieren, nahezu aussichtslos. Es ist übersichtlicher, alle disruptiven Änderungen hinter ein Master Flag zu bekommen, alle Sub-Commits schrittweise zusammenzuführen und bereitzustellen und das Flag umzustellen, sobald alle Teile an der richtigen Stelle sind.
Auch sind Feature Flags sinnvoll, wenn Sie keine Kontrolle über Ihre Softwareverteilung haben. Denken Sie zum Beispiel an die Facebook-Android-App, die Code von Hunderten verschiedenen Teams enthält und ihn als eine einzige Binärdatei bereitstellt. In solchen Szenarien sind Rollbacks manchmal unmöglich – aus praktischen, politischen, bürokratischen oder sogar Marketing-Gründen. Feature Flags ermöglichen es dann, neue Funktionen zu aktivieren oder das Risiko bestimmter Änderungen zu verringern, ohne dass ein Rollback gemacht werden muss oder neue Binärdateien bereitgestellt werden müssen.
Bei Reddit hat jemand über einen ähnlichen Anwendungsfall für Feature Flags geschrieben(öffnet im neuen Fenster) : Wenn nämlich aus Marketing-Gründen ein bestimmtes Einführungsdatum festgelegt wird, der Code aber früher bereitgestellt werden soll, um die Stabilität zu gewährleisten. Hier hilft ein dynamisches Feature Flag, das sich automatisch zu einem bestimmten Zeitpunkt aktiviert.
Feature Flags ersetzen keine gründlichen Tests
Die eben genannten sind gute Anwendungsfälle für Feature Flags. Ich habe aber auch Teams erlebt, die sich bei der Verwendung von Feature Flags verzettelt und viel zu weitgehende Vorgaben erlassen haben. Zum Beispiel, dass jede einzelne Codeänderung hinter einem Feature Flag stehen sollte, "nur für den Fall, dass wir einen Fehler gemacht haben" .
Risikomanagement sollte für alle Teams vorrangig sein. Allerdings gibt es dafür bessere Wege als Feature Flags, insbesondere wenn das Team die Kontrolle über die Verteilung hat. Die überwiegende Mehrheit der Bugs sollte von automatisierten Test-Suites und/oder dem QA-Prozess abgefangen werden – und die Nachzügler mit schrittweisen Deployments, Warnungen im Produktionsbetrieb und Rollbacks .
Übrigens lautet die Empfehlung bei Firmen wie Google, beim Entdecken eines Problems zuerst einen Rollback durchzuführen und das Problem später zu untersuchen(öffnet im neuen Fenster) :
"Wir haben bei Google schon oft gesehen, dass ein eilig eingesetzter Roll-Forward-Fix entweder das ursprüngliche Problem nicht behebt oder alles noch schlimmer macht. Selbst wenn er das Problem behebt, kann es sein, dass dadurch andere latente Fehler im System aufgedeckt werden. Damit entfernt man sich immer weiter von einem bekannten, gut funktionierenden Zustand hin zu einer unbekannten Version ohne die üblichen strengen QA-Tests. Bei Google ist unsere Philosophie, dass Rollbacks normal sind. Wenn ein Fehler in einer neuen Version gefunden oder vermutet wird, macht das veröffentlichende Team zuerst einen Rollback und geht dem Problem erst danach auf den Grund."
Wenn es akute Probleme mit dem Code gibt, ist das Letzte, was Sie tun möchten, erst einmal lange nach der Ursache zu suchen und sich zu fragen, welcher Flag-Flip das Problem beheben wird. Zumal es keine Garantie dafür gibt, dass es diesen Flag-Flip, der das Problem löst, überhaupt gibt.
Feature Flags sind eine schlechte Alternative zu binären Rollbacks, und sie sind definitiv kein Ersatz für eine gute automatisierte Testsuite und einen robusten QA-Prozess. Wenn Sie sich auf Feature Flags verlassen, um Fehler im produktiven Betrieb zu beheben, sollten Sie kurz innehalten und die Arbeitsweise Ihres Teams überdenken. Denn Risiken zu scheuen, ist oft ein erstes Anzeichen dafür, dass es mit einer Software bergab geht.
Tod durch Feature Flags
Vielleicht fragen Sie sich an dieser Stelle, warum Feature Flags nicht trotzdem verwendet werden sollten, Stichwort: Defense-in-Depth-Ansatz(öffnet im neuen Fenster) . Außerdem schadet es doch nie, etwas mehr Flexibilität im Detail zu haben, oder?
Dazu muss man wissen: Feature Flags sind zwar für einige Anwendungsfälle sehr gut geeignet, sie haben jedoch ihren Preis. Softwareentwicklung ist in erster Linie eine Übung im Umgang mit Komplexität und jedes Feature Flag verdoppelt sofort die Zahl der Sonderfälle, die Programmierer verstehen müssen und mit denen der Code umgehen muss: "Aber was würde passieren, wenn Foo aktiviert und Bar deaktiviert ist, und wir am selben Tag unabhängige A/B-Tests mit Baz und Kaz durchführen?"
Nach meiner Erfahrung kann und wird dieser sprunghafte Anstieg der Komplexität zu Fehlern führen. Ganz zu schweigen von der Verlangsamung, mit der Ihr Team Änderungen vornehmen kann.
Um kurz eine amüsante Anekdote aus dem Internet zu zitieren(öffnet im neuen Fenster) : "Ein Flag, das seit einem Jahr nicht mehr auf 'aus' gesetzt wurde, kann große Fehlentwicklungen verbergen. Bei meinem letzten Job hatten wir zwei große Ausfälle in ebenso vielen Jahren, als Flags plötzlich auf 'aus' gesetzt wurden, weil das Feature-Flag-System den Status der Flags nicht mehr zurückgeben konnte."
"Aber Feature Flags sind doch nur temporär. Sie sollten so schnell wie möglich entfernt werden!"
Klar. Aber wir sollten auch verhindern, dass sich unsere technischen Schulden anhäufen und wir sollten jedes einzelne Best Practice strikt befolgen. Leider passiert das in keiner Firma. Sogar in sehr guten Teams wird die Frage nach den technischen Schulden zugunsten neuer Anforderungen oft zurückgedrängt. Neuankömmlinge im Team oder ausscheidende Mitarbeiter sind nicht immer diszipliniert genug, um nach einem erfolgreichen Rollout ihre Flags zu entfernen – und manchmal wird so etwas einfach übersehen und vergessen.
Bei Hackernews hat jemand darauf hingewiesen(öffnet im neuen Fenster) , dass die Release-Version von Windows (Stand: September 2020) "ungefähr 2.500 Feature Flags hat. Einige sind permanent in der On-Position festgeklemmt, einige in der Off-Position, und der Rest kann durch seine experimentation frameworks und durch Hacker konfiguriert werden".
Nichts verdeutlicht das besser als das Debakel mit KCG(öffnet im neuen Fenster) , als die Finanzfirma innerhalb von 30 Minuten eine halbe Milliarde Dollar verlor und fast bankrott ging – teilweise aufgrund von Dead Code, der sich hinter einem Feature Flag befand(öffnet im neuen Fenster) .
"Die Ursache für den Ausfall war auf mehrere Faktoren zurückzuführen. Einer der wichtigsten war jedoch, dass ein Flag, das zuvor für die Aktivierung von Power Peg verwendet wurde, für die Verwendung in einer neuen Funktionalität umgewidmet wurde. (...) Power Peg war seit 2003 nicht mehr in Benutzung, befand sich aber rund acht Jahre später immer noch in der Codebasis.
Im Jahr 2005 wurde eine Änderung am Power-Peg-Code vorgenommen, die versehentlich Sicherheitsprüfungen deaktivierte, die ein solches Szenario verhindert hätten. Dieses Update wurde damals jedoch auf einem Produktivsystem eingesetzt, obwohl die Power-Peg-Funktionalität nicht überprüft worden war."
Feature Flags sind ein mächtiges Werkzeug, das helfen kann, mit neuen Funktionen zu experimentieren, den Rollout komplexer Projekte zu verwalten und Probleme zu vermeiden, die entstehen, wenn die Deployments des eigenen Teams nicht kontrolliert werden können.
Aber sie haben ihren Preis: höhere Code-Komplexität, technische Schulden, eine langsamere Entwicklungsgeschwindigkeit und unweigerlich auch Bugs.
So toll das wäre, aber es gibt hier kein Patentrezept. Wägen Sie die Vor- und Nachteile ab und setzen Sie dieses Werkzeug mit Bedacht ein, wenn es sinnvoll ist.
- Anzeige Hier geht es zum Handbuch für Softwareentwickler bei Amazon Wenn Sie auf diesen Link klicken und darüber einkaufen, erhält Golem eine kleine Provision. Dies ändert nichts am Preis der Artikel.