Java Feature Toggles – Wie kann man sie im Continuous Deployment verwenden?

/ 16.07.2023 Java

Wer im Outside-in-Development Style arbeitet, will die den jeweiligen  Stakeholdern so gut wie möglich die Features präsentieren; meistens macht man das dann mit einer Art UI-Mock-up, das zeigt, wie die Funktionalität aus der Sicht des Endbenutzers aussehen wird. Auch wenn dort noch keine Domäne oder Datenbank implementiert ist, können ein Walking Skeleton für die Präsentation genutzt werden, das die grundlegenden Komponenten des Systems enthält. Damit die Präsentation in einer Staging-Umgebung und nicht in einer Produktionsumgebung erfolgt, verwenden wir so genannte Feature Toggles/Flags oder Feature Switches.  Wie lässt sich die Möglichkeit der Nutzung der Features durch verschiedene Benutzergruppen ohne implementieren, ohne ein Deployment durchzuführen? Gibt es eine Möglichkeit, Funktionen in einer Produktionsumgebung effektiv zu testen und sie bei Bedarf sofort außer Betrieb zu nehmen? Wir werden diese Fragen beantworten, indem wir uns den Feature Flags oder auch Feature Toggles widmen.

Was sind Feature Toggles?

Feature Toggles, auch bekannt als Feature Flags, sind eine Technik, die es Entwicklern ermöglicht, bestimmte Funktionen in Anwendungen ein- oder auszuschalten, ohne neuen Code implementieren zu müssen. Dies kann mit einem Beispiel veranschaulicht werden: Wenn Sie in Ihrem Haus ein Licht einschalten, müssen Sie nicht jedes Mal die Verkabelung ändern, sondern nur den Schalter betätigen, und das war’s. Wenn Sie das Licht wieder ausschalten wollen, drücken Sie den Schalter erneut, und das Licht geht aus. Das Gleiche gilt für Feature Flags; sie können eine neue Funktion in Ihrer Software oder Plattform ohne Ausfallzeiten freigeben. Diese lässt sich somit jederzeit durchführen, auch während der Betriebszeiten. Das bedeutet: Ein solches Toggle macht es möglich, den Pfad im Code dynamisch zu wählen, sei es zum Zeitpunkt der Erstellung oder Ausführung des Produkts oder in der Ausführungsumgebung. Die Verwendung von “if” im Code ermöglicht es, das Verhalten des Codes zu ändern, ohne ihn neu zu schreiben und alles in der Deployment Pipeline zu verarbeiten müssen. Gleichzeitig können Sie mit dieser Technik Ihren Code viel häufiger integrieren, da Sie nicht wochenlang an Ihrem Funktionszweig festsitzen und warten müssen, bis die Funktion vollständig fertiggestellt ist, bevor Sie sie in den restlichen Code integrieren. Sie können unfertige Funktionen mit dem Rest des Codes zusammenführen, sie in den “MAIN”-Hauptzweig der Versionskontrolle legen und diesen unfertigen Code in die Produktion einbringen (natürlich, auch um die Produktion nicht zu spoilen ?). Java Feature Toggles _1

Vorteile von Feature Flags

Mit Feature Flags können Teams Feature-Releases kontrollieren, A/B-Tests durchführen, technische Schulden verwalten und eine reibungslosere Bereitstellung gewährleisten. Hier sind die wichtigsten Vorteile von Feature Flags im Code: 1. Geringeres Risiko der Umsetzung – Sicherheit von Feature Toggles Funktionskennzeichen geben ein Gefühl der psychologischen Sicherheit, weil wir wissen, dass ich dieses Kennzeichen jederzeit ausschalten kann und diese Funktion nicht zu sehen sein wird. Wir können dadurch befreiter Code integrieren  und herumexperimentieren, indem wir nach und nach verschiedene Versionen der Funktion zu implementieren und austesten. 2. Schnellere Bereitstellung von Software  Die Toggles ermöglichen es, neue Funktionen in einer Produktionsumgebung zu testen, ohne sie allen Benutzern zur Verfügung zu stellen, unabhängig von der Hauptcodebasis. 3. Schnelleres Feedback erhalten  Mit Feature Flags ist es möglich, internes Feedback von den Stakeholdern meines Unternehmens zu sammeln und Änderungen an unfertigen Funktionen vorzunehmen. 4. Verbesserter Entwicklungsprozess  Feature Flags helfen dabei, Benutzer auf der Grundlage verschiedener Attribute zu segmentieren, verschiedene Feature-Varianten zu erstellen und zu vergleichen und ihre Leistung zu messen, um das Benutzererlebnis und die Unternehmensziele zu optimieren. 5. Kontrolle und Überwachung  Flaggen bestimmen, wer auf Funktionen zugreifen kann, und sammeln Feedback und Daten, bevor sie für alle verfügbar gemacht werden. Sie können auch verwendet werden, um Funktionen schrittweise für eine Untergruppe von Benutzern verfügbar zu machen und ihre Leistung und Auswirkungen zu überwachen. 6. Schnellere Verhaltensänderungen, ohne dass der Quellcode geändert werden muss.  Mit Feature Toggles können Sie das Verhalten des Systems jederzeit ändern. Sie erfordern möglicherweise nur ein erneutes Deployment, und selbst dieser Schritt kann übersprungen werden, wenn Sie z. B. Spring Cloud Config verwenden, mit dem Sie die Anwendungskonfiguration ändern können, ohne ihre Verfügbarkeit negativ zu beeinflussen.

Arten von Feature Flags und ihr Zweck

Feature Flags können nach Martin Fowler wie folgt klassifiziert werden:
  • Freigabeschalter – Mit diesen Switches können Sie Code bereitstellen, der noch nicht fertiggestellt ist, und unvollständige Funktionen vor den Benutzern verbergen.
  • Experiment-Toggles – Dieser Typ wird bei A/B-Tests verwendet. Meistens bleiben diese so lange implementiert, wie wir Schlussfolgerungen aus den Ergebnissen des Experiments ziehen müssen.
  • Ops Toggles – Werden hauptsächlich verwendet, um die betrieblichen Aspekte des Systems durch die Personen zu kontrollieren, die die Anwendung verwalten. Sie können verwendet werden, um bestimmte Toggles zu deaktivieren, die für das ordnungsgemäße Funktionieren der Anwendung nicht erforderlich sind, z. B. bei hoher Serverlast.
  • Berechtigungsschalter – Dieser Typ verwaltet Funktionen, die für verschiedene Benutzergruppen verfügbar sind. Sie werden häufig zur Verwaltung von Premium- und Early-Access-Funktionen verwendet.
Java Feature Toggles_2

Möglichkeiten zur Implementierung von Feature Flags

In Java gibt es verschiedene Ansätze für die Implementierung von Funktionsumschaltungen, z. B. Schalter, die in einer Konfigurationsdatei auf der Grundlage einer Datenbank vorhanden sind, oder die Verwendung externer Dienste für die Verwaltung dieser Schalter. Manchmal gibt es eine zusätzliche Benutzerschnittstellenanwendung mit einer Liste von Funktionen und einem “Schalter” neben ihnen. Wenn der Schalter auf “on” steht, ist die Funktion in der Zielanwendung verfügbar.  Im Folgenden werden wir die Vor- und Nachteile dieser Ansätze erörtern und erörtern, wann sie eingesetzt werden sollten.

Konfigurationsbasierte Flags

Bei diesem Ansatz werden Funktionsschalter in Konfigurationsdateien definiert, z. B. in Properties, YAML oder JSON. Die Anwendung liest diese Konfigurationsdateien zur Laufzeit und aktiviert oder deaktiviert Funktionen basierend auf den Werten der Schalter. Vorteile: 
  • Die in der Konfigurationsdatei vorhandenen Schalter sind einfach zu implementieren und zu verstehen.
  • Sie können die Flags ändern, ohne den Code zu ändern oder die Anwendung neu zu implementieren.
  • Konfigurationsdateien können mit Versionskontrollsystemen verwaltet werden, was eine Nachverfolgung und Prüfung ermöglicht.
Benachteiligungen:  
  • Begrenztes Kontextbewusstsein: Konfigurationsbasierte Switches unterstützen in der Regel keine dynamische Funktionsaktivierung auf der Grundlage von Benutzerrollen, Berechtigungen oder anderen kontextbezogenen Faktoren.
  • Da die Anzahl der Funktionen und Schalter zunimmt, kann die Verwaltung der Konfigurationsdateien zu einer Herausforderung werden.
Wann zu verwenden: Konfigurationsbasierte Switches sind geeignet, wenn Sie eine einfache und statische Methode zur Steuerung der Funktionsverfügbarkeit benötigen, die keine Änderungen zur Ausführungszeit oder Berücksichtigung des Kontexts erfordert.

Datenbankbasierte Feature Flags 

Bei diesem Ansatz werden die Umschaltfunktionen in einer Datenbank oder einem zentralisierten Konfigurationsmanagementsystem gespeichert und verwaltet. Die Anwendung fragt die Datenbank ab oder liest die Konfiguration zur Laufzeit, um festzustellen, welche Funktionen aktiviert oder deaktiviert werden sollen. Vorteile:
  • Sie können Toggles zur Laufzeit ändern, ohne die Anwendung neu zu starten oder den Code zu ändern.
  • Kontexterkennung: Schaltflächen können mit Benutzerrollen, Berechtigungen oder anderen in der Datenbank gespeicherten Kontextinformationen verknüpft werden.
  • Skalierbarkeit: Die zentrale Speicherung ermöglicht die Verwaltung von Feature Flags über mehrere Instanzen oder Umgebungen hinweg.
Nachteile:
  • Die Implementierung von Feature Flags erfordert zusätzliche Infrastruktur, wie z. B. eine Datenbank oder ein Konfigurationsmanagementsystem.
  • Häufige Datenbankabfragen können die Leistung beeinträchtigen, insbesondere wenn die Umschaltvorgänge für jede Benutzeranfrage ausgewertet werden.
 Wann zu verwenden: Datenbankbasierte Flags sind nützlich, wenn Sie eine dynamische Kontrolle über die Verfügbarkeit von Funktionen benötigen, kontextabhängige Faktoren erfordern und einen Neustart von Anwendungen oder die Bereitstellung von Code zur Änderung von Schaltern vermeiden möchten. Sie sind besonders in großen Anwendungen oder verteilten Systemen von Vorteil.

Externe Tools zur Verwaltung von Feature Flags 

Es gibt mehrere Lösungen für die Verwaltung von Feature Flags. Es sind Java Entwicklungstools und mehrere SDK-Bibliotheken in Java verfügbar, die zur Implementierung von Feature Toggles verwendet werden können. Diese Bibliotheken bieten unterschiedliche Funktionen, Integrationsoptionen und Verwaltungsmöglichkeiten. Bei der Auswahl einer SDK-Bibliothek für Ihr Java-Projekt sollten Sie Faktoren wie folgende berücksichtigen die Kompatibilität der Rahmenbedingungen,, die Anforderungen an das Funktionsmanagement, die Benutzerfreundlichkeit und die Unterstützung durch die Community, um die für Sie am besten geeignete Lösung zu finden.  Einige der beliebtesten Tools sind:  Togglz Vorteile: 
  • Leicht und einfach zu bedienen.
  • Lässt sich gut mit Java EE und Spring-Frameworks integrieren.
  • Bietet verschiedene Strategien zur Aktivierung von Funktionsknebeln.
  • Unterstützt benutzerdefinierte Konfigurationsoptionen
  • Wird von der Community aktiv unterstützt und regelmäßig aktualisiert.
Nachteile: 
  • Im Vergleich zu anderen Bibliotheken verfügt sie nur über begrenzte Möglichkeiten zur Verwaltung erweiterter Funktionen
  • Eingeschränkte Unterstützung für die Fernverwaltung und -konfiguration von Funktionsmerkmalen.
FF4J (Feature Flipping für Java) Vorteile: 
  • Dynamisches Feature Management, einschließlich des Umschaltens auf der Grundlage von Berechtigungen.
  • Nahtlose Integration mit Java-Frameworks wie Spring, CDI und JAX-RS.
  • Bietet eine Web-Konsole zur Verwaltung von Feature Flags.
  • Bietet verschiedene Aktivierungs- und Deaktivierungsregeln für Schaltfunktionen.
  • Open-Source-Software mit einer aktiven Community und regelmäßigen Updates.
Nachteile: 
  • Ziemlich komplizierte Dokumentation
  • Nicht sehr flexible Konfigurationsmöglichkeiten im Vergleich zu anderen Bibliotheken.
Unleash Vorteile: 
  • Erweiterte Funktionstasten.
  • Mehrere Aktivierungsstrategien und Targeting-Optionen.
  • Zentraler Server für die Verwaltung von Funktionen und Dashboard.
  • Unterstützt die Aktualisierung der Konfiguration in Echtzeit.
  • Gute Integrationsmöglichkeiten und SDK-Unterstützung für Java.
Nachteile: 
  • Benötigt eine externe Infrastruktur oder einen externen Dienst, um ihre Möglichkeiten voll ausschöpfen zu können.
LaunchDarkly Vorteile: 
  • Umfassende Funktionsmanagement-Plattform mit leistungsstarken Funktionen für die Funktionsumschaltung.
  • Es unterstützt benutzerbasiertes Targeting, A/B-Tests und benutzerdefinierte Aktivierungsregeln.
  • Es verfügt über eine Weboberfläche zur Verwaltung von Funktionskennzeichen und Konfigurationen.
  • Nahtlose Integration mit verschiedenen Entwicklungs-Frameworks und -Diensten.
  • Es bietet umfangreiche Dokumentation und Ressourcen.
Nachteile: 
  • Für den Zugriff auf erweiterte Funktionen und den vollen Funktionsumfang ist ein Abonnement erforderlich.
  • Bei kleinen Projekten oder Start-ups kann der Preis eine Rolle spielen.
  • Abhängigkeit von einem Dienst eines Drittanbieters für die Verwaltung von Umschaltvorgängen.
Spring Cloud Config Profis 
  • Zentralisierte Standorte für die Verwaltung von Konfigurationseigenschaften, einschließlich Feature-Switches. Dies erleichtert die Aktualisierung und Pflege von Feature Flags über mehrere Dienste oder Instanzen hinweg.
  • Dynamische Upgrades – Ermöglicht die Änderung von Funktionskennzeichenwerten in Echtzeit, ohne dass die Anwendung neu gestartet oder neu bereitgestellt werden muss. Diese Flexibilität ermöglicht die schnelle Erprobung und Bereitstellung neuer Funktionen.
  • Versionskontrolle – In SCC können Änderungen nachverfolgt und frühere Versionen bei Bedarf wiederhergestellt werden, was eine bessere Kontrolle der Konfigurationshistorie ermöglicht.
  • Sicherheit – Spring Cloud Config bietet Optionen für die Sicherung von Feature-Toggle-Eigenschaften durch Verschlüsselungs- und Zugriffskontrollmechanismen. Dies garantiert den Schutz vor unberechtigtem Zugriff.
Nachteile 
  • Netzwerkabhängigkeit: Wenn der Konfigurationsserver nicht verfügbar ist, kann die Anwendung möglicherweise keine aktualisierten Feature Toggles herunterladen, was das Systemverhalten beeinträchtigen kann.
  • Erhöhte Komplexität: Die Integration von Spring Cloud Config für Feature Flags erhöht die Komplexität der Systemarchitektur. Sie erfordert die Verwaltung des Konfigurationsservers, die Abwicklung der Kommunikation zwischen dem Server und der Anwendung und die Sicherstellung der Konsistenz zwischen den Diensten.
Je nach den Anforderungen der Anwendung können Sie die oben genannten Ansätze kombinieren, um Feature Flags zu implementieren. Letztendlich hängt die Entscheidung, wie ein Flag im Code implementiert werden soll, von Faktoren wie der Komplexität der Anwendung, dem erforderlichen Maß an Kontrolle, dem Bedarf an Laufzeitänderungen und den Kompromissen ab, die Sie in Bezug auf Codeänderungen, Implementierungen und Leistung eingehen möchten.

Warum sollte man die Bereitstellung von der Freigabe trennen?

Mit der bedingten Option “if” können Sie die Bereitstellung von der Freigabe trennen, da hinter diesem “if” Informationen darüber stehen, wer das entsprechende Feature tatsächlich sehen wird und für wen wir sie verbergen werden.

Warum ist es wichtig, den Unterschied zwischen dem Deployment und der Freigabe eines Projekts zu verstehen?

Die beiden oben genannten Konzepte unterscheiden sich. Das Deployment/ die Bereitstellung oder Implementierung ist ein technisches Ereignis, bei dem wir Änderungen an der Software vornehmen und den Code schließlich in die Produktionsumgebung übertragen, diese müssen dann noch freigegeben werden. Spannend wird es, wenn diese neuen Funktionen für die Endbenutzer verfügbar werden. In diesem Fall können wir mit Funktionskennzeichen die Freigabe dieser neuen Funktion auf der Bereitstellungsplattform steuern, d. h. wir wählen aus, wer die neuen Versionen der Software sehen kann.
Zusammenfassend lässt sich sagen, dass die Feature Flags die beiden Funktionen trennen. Wir können jeden Tag neue Software bereitstellen, aber jetzt können wir entscheiden, wem und wann wir neue Versionen präsentieren.

Warum sind Feature Flags in einem kontinuierlichen Bereitstellungs- und Verteilungsmechanismus wichtig?

Feature-Flagging ermöglicht effizientes CI/CD, so dass Entwickler ihre Arbeit häufig in ein gemeinsames Repository einbringen können, ohne sich Sorgen machen zu müssen, dass etwas kaputt geht oder dass Endbenutzer auf unfertige Funktionen zugreifen. Die Flags geben Ihnen die Kontrolle über das Verhalten der Anwendung oder Plattform, was bedeutet, dass der gesamte Code immer bereitgestellt wird, aber einige Zweige des Codes können auf neue Funktionen des geänderten Verhaltens getestet werden, oder Sie können sie deaktivieren, bis die Flag aktiviert ist. Jedes Mal, wenn Sie ein Toggle aktivieren, ist dieser Code für die Benutzer verfügbar.

Testen von mit Feature Flags versehenem Code

Es hängt von Ihrer Teststrategie ab, ob Sie Unit-Tests oder manuelle Tests usw. durchführen. Es kommt nicht darauf an, jede mögliche Kombination von Funktionskennzeichen zu testen, sondern Tests durchzuführen, bei denen eine Wahrscheinlichkeit besteht, dass etwas passiert. Ein Test schlägt auch fehl, wenn die zu testende Funktion derzeit deaktiviert ist. Daher ist es am besten, die Tests aus dem Hauptprozessablauf zu entfernen, bis die Funktion offiziell freigegeben wird. Bis dahin ist es am besten, die Tests nur bei Bedarf und nachdem die Funktion freigegeben wurde, durchzuführen. Sobald die Funktion endgültig freigegeben ist, können die Tests in den Haupttestablauf aufgenommen werden.

Welche Probleme entstehen, wenn wir die Feature Flags nicht entfernen?

Die Art und Weise, wie Funktionsschalter verwaltet werden, zeigt die Qualität der Organisation. Werden Funktionskennzeichen nach ihrer vorgesehenen Verwendung nicht entfernt, kann dies zu verschiedenen Problemen führen:
  • Technische Schulden – In der Codebasis verbleibende Feature Flags können sich im Laufe der Zeit ansammeln, wodurch die Codebasis komplexer und schwieriger zu warten, zu verstehen und zu debuggen wird.
  • Erhöhter Test- und Wartungsaufwand – Wenn Feature Flags nicht entfernt werden, sind sie immer noch Teil des Testprozesses, was bedeutet, dass die Tester die zugehörigen Codepfade testen müssen, auch wenn sie nicht mehr relevant sind.
  • Sicherheitsrisiken – Wenn ungenutzte und vergessene Funktionskennzeichen den Zugang zu sensiblen Funktionen kontrollieren oder ungesicherte Funktionen offenlegen, können sie bei unzureichender Sicherung angegriffen werden.
  • Leistungsverschlechterung – Feature Toggles beinhalten oft zusätzliche, bedingte Kontrollen im Code. Wenn diese Prüfungen nicht entfernt werden, nachdem die Funktion nicht mehr benötigt wird, können sie die Anwendung verlangsamen.
  • Kompatibilitätsprobleme – Feature Flags können mit anderen Teilen der Codebasis, Abhängigkeiten oder Integrationen interagieren. Das Vorhandensein unbenutzter Feature Flags kann zu Konflikten mit anderen Codes führen oder unbeabsichtigtes Verhalten hervorrufen.
Um diese Probleme zu vermeiden, ist es notwendig, rigoros vorzugehen und sich an eine Reihe von Praktiken zu halten, um Feature Flags zu entfernen, wenn sie ihren Zweck erfüllt haben. Dieser Prozess sollte regelmäßige Codeüberprüfungen, Initiativen zur Beseitigung von Flags und eine Dokumentation umfassen, um sicherzustellen, dass Flags während des gesamten Agile Entwicklungszyklus mit Java ordnungsgemäß verwaltet werden. Was kann passieren, wenn die Flaggenfunktion missbraucht wird? Das Unternehmen könnte Millionen an Einnahmen verlieren. So wie das Unternehmen Knights Capital, das in 28 Minuten 460 Millionen Dollar verlor ?.

Zusammenfassung

Um die Vorteile des Feature Toggling zu maximieren und gleichzeitig die Herausforderungen und Risiken zu minimieren, sollten Sie den Lebenszyklus definieren und ein dokumentiertes Feature-Flag-System entsprechend verwalten. Sicherlich können Feature Flags viele Vorteile mit sich bringen, wie z. B. eine benutzergesteuerte Entwicklung und die Verringerung der Risiken, die mit größeren Versionen verbunden sind.   Das Wichtigste ist jedoch, dass gut ausgearbeitete Feature Flags in Form von einfachem Code und Konfigurationswerten einfach zu pflegen sein müssen. Daher lohnt es sich immer zu überlegen, welche Komplexität wir in den Code einbringen und ob das gleiche Ergebnis auf einfachere Weise erreicht werden kann.
Kategorien Java


Mariola Nowak Content Writer
Tomasz Kluza Senior Full-Stack Developer

Design, Entwicklung, DevOps oder Cloud - welches Team brauchen Sie, um die Arbeit an Ihren Projekten zu beschleunigen?
Chatten Sie mit unseren Beratungspartnern, um herauszufinden, ob wir gut zusammenpassen.

Jakub Orczyk

Vorstandsmitglied /Verkaufsdirektor

Buchen Sie eine kostenlose Beratung
kuba (1)