paint-brush
So übermitteln Sie Änderungen sicher an die Produktionvon@israel_hlc
16,509 Lesungen
16,509 Lesungen

So übermitteln Sie Änderungen sicher an die Produktion

von 10m2023/10/24
Read on Terminal Reader

Zu lang; Lesen

Wir alle kennen die Übung, oder? Nachdem wir mit der Arbeit an einer Codeänderung fertig sind und sie [hoffentlich] auf unserem lokalen Computer testen, schieben wir die Änderung in die nächste Phase des Zyklus. Lokale Tests sind sehr voreingenommen und im Idealfall möchten wir die Änderung in einer stabileren Umgebung validieren (und nicht nur dem Standpunkt des Ingenieurs folgen, der die Änderung implementiert hat).
featured image - So übermitteln Sie Änderungen sicher an die Produktion
 HackerNoon profile picture

Wir alle kennen die Übung, oder? Nachdem wir mit der Arbeit an einer Codeänderung fertig sind und sie [hoffentlich] auf unserem lokalen Computer testen, schieben wir die Änderung in die nächste Phase des Zyklus. Lokale Tests sind sehr voreingenommen, und im Idealfall möchten wir die Änderung in einer stabileren Umgebung validieren (und nicht nur dem Standpunkt des Ingenieurs folgen, der die Änderung implementiert hat).


Ein nächster Schritt erscheint hier ganz natürlich: Übertragen Sie die Änderungen in eine zuverlässige Staging-Umgebung und lassen Sie sich von Partnern (QAs, PMs, andere Ingenieure) bei der Validierung helfen, bevor Sie die Änderungen verschieben. Daraufhin würden Fehler behoben und erneut validiert, bis wir glauben, dass es gut genug ist, um es in die Produktion zu bringen. Großartig!


In den meisten Fällen geschieht dies jedoch einfach nicht. Es kann verschiedene Gründe haben, aber unabhängig vom Grund ist die Konsequenz, dass wir häufig Änderungen an Produktionsservern vorantreiben müssen, bevor diese ausreichend getestet oder validiert werden.


Das Problem ist ... Was ist, wenn etwas kaputt geht? Wie erkennt man eigentlich Probleme früher? Gute Nachrichten: Es ist möglich, einige Tools und Praktiken zu übernehmen, um das Testen und Validieren in der Produktion nicht nur zu einer sicheren Praxis für Sie und Ihr Unternehmen, sondern vielleicht sogar zu einer guten Idee zu machen.

Die Basis: Metriken

Bevor wir mit dem Testen in der Produktion beginnen, müssen wir über Metriken sprechen: Wir benötigen sie, um zu validieren, dass die von uns ausgelieferte Änderung den gewünschten Effekt erzeugt, keine unerwünschten Nebenwirkungen verursacht, das Produkt noch stabil ist usw. Ohne gut -Etablierte Metriken, wir sind grundsätzlich blind, wenn wir die Änderungen einführen. In vielen Themen des Artikels beziehen wir uns auf Metriken. Schauen wir uns also zwei verschiedene Arten von Metriken an, die wir im Auge behalten sollten.

Geschäftskennzahlen

Geschäftsbezogene Kennzahlen wie KPIs, Ziele und Benutzerverhalten sollten nach der Implementierung von Änderungen überwacht werden, um die Auswirkungen zu bewerten. Identifizieren Sie vor jeder Änderung die Kennzahlen, von denen erwartet wird, dass sie betroffen sind. Ebenso wichtig sind Leitplanken, Indikatoren dafür, was sich nicht ändern sollte. Unvorhergesehene Änderungen dieser Leitplanken können auf Probleme mit der neuen Änderung hinweisen und eine Überprüfung erforderlich machen.

Technische Kennzahlen

Sobald die Geschäftskennzahlen definiert sind, ist es auch wichtig, die technischen Kennzahlen zu verstehen. Diese sind von grundlegender Bedeutung, um sicherzustellen, dass die Systeme fehlerfrei bleiben, wenn im Laufe der Zeit Änderungen eingeführt werden. Hier geht es um Systemstabilität, Fehlerrate, Volumen, Einschränkungen der Maschinenkapazität usw.


Gute technische Kennzahlen sind auch nützlich, um bei Geschäftskennzahlen beobachtete Probleme zu erklären oder schnell die Grundursache für Regressionen zu finden. Nehmen wir zum Beispiel an, wir beobachten, dass Benutzer nach dem Rollout der letzten Version viel weniger mit einer bestimmten Funktion interagieren. Ein Anstieg der Anforderungszeitüberschreitungen oder Fehlerraten könnte schnell zeigen, welche Dienste/Endpunkte das Problem verursachen.

Überwachung

Wir haben klar definierte geschäftliche und technische Kennzahlen, gut! Jetzt müssen wir sie überwachen. Es gibt viele Möglichkeiten, dies zu tun, aber ein üblicher erster Schritt besteht darin, Dashboards zu erstellen, die Kennzahlen über einen längeren Zeitraum verfolgen und so ungewöhnliche Spitzen leicht erkennen. Noch besser ist es, wenn das Dashboard eine schnelle Filterung von Daten basierend auf bestimmten Segmenten ermöglicht, die für das Unternehmen besonders relevant sein könnten. Die aktive Überwachung von Dashboards ist eine gute Möglichkeit, die Auswirkungen einer neuen Änderung im System schnell zu visualisieren. Einige Unternehmen halten die aktive Überwachung für so wichtig, dass sie sogar rund um die Uhr Überwachungsschichten haben, um Probleme so früh wie möglich zu erkennen und zu beheben.


Eine weitere gute Möglichkeit, Metriken zu überwachen, ist die automatische Erkennung und Warnung. Bei wichtigen Kennzahlen können Warnungen eine Echtzeitbenachrichtigung bereitstellen, wenn etwas schief zu sein scheint. Nehmen wir an, wir beginnen mit der Einführung einer Funktion und erhalten einige Minuten nach Beginn des Prozesses eine Warnung, dass die Fehlerrate einen bestimmten Schwellenwert überschreitet. Diese frühzeitige Benachrichtigung kann uns daran hindern, die Änderung in der Produktion weiter zu verbreiten, und uns viele Probleme ersparen!


Schließlich ist es wichtig, sich darüber im Klaren zu sein, wie viele Informationen wir unter welchen Umständen benötigen. Während Dashboards sehr nützlich sind, um einen visuellen Einblick in die Produkt- und Systemleistung zu geben, führt das Hinzufügen von 1.000 verschiedenen Diagrammen eher zu Verwirrung als zu Klarheit. Wenn wir täglich 1.000 Warnmeldungen erhalten, ist es ebenfalls unmöglich, sie zu untersuchen und darauf zu reagieren, und sie werden am Ende ignoriert.

Sicherere Landung

Kennzahlen definiert, Überwachung vorhanden, großartig! Werfen wir nun einen Blick auf einige Tools und Strategien, die uns helfen, Probleme zu vermeiden, Probleme früher zu erkennen und Auswirkungen auf die Produktion zu minimieren. Abhängig davon, wie die Produktionsumgebung eingerichtet ist, sind einige davon schwieriger zu implementieren als andere und ergeben in Kombination möglicherweise nicht einmal viel Sinn. Jeder Punkt hier könnte uns jedoch dabei helfen, einer sicheren und stabilen Produktionsumgebung näher zu kommen.

Automatisierte Tests

Automatisierte Tests, die oft außer Acht gelassen werden, wenn Projekte aus der Bahn geraten, können die Entwicklung beschleunigen und Änderungen an der Produktion sicherer und schneller machen. Je früher Probleme erkannt werden, desto schneller können sie behoben werden, wodurch sich der Gesamtzeitaufwand für den Prozess verringert. Der Prozess, Änderungen rückgängig zu machen, zu reparieren und erneut voranzutreiben, ist in der Regel sehr stressig und kann wertvolle Zeit kosten.


Das Streben nach einer 100-prozentigen Testabdeckung mit Unit-, Integrations- und End-to-End-Tests mag für die meisten Projekte idealistisch sein. Priorisieren Sie Tests stattdessen nach Aufwand und Nutzen. Metriken können dabei Orientierung geben: Die Abdeckung zentraler Geschäftsfunktionen ist wahrscheinlich wichtiger als Nischenfunktionen mit geringerer Auswirkung, oder? Beginnen Sie mit den Kernfunktionen und erweitern Sie diese, während sich das System weiterentwickelt.


Der Prozess der Veröffentlichung in der Produktion sollte die Ausführung der Testsuite vor der Bereitstellung in der Produktion umfassen. Testfehler sollten die Veröffentlichung unterbrechen und so Produktionsprobleme verhindern. Es ist besser, die Veröffentlichung einer Funktion zu verzögern, als am nächsten Tag festzustellen, dass sie völlig fehlerhaft ist.

Hundefutter

Beim Dogfooding wird eine Funktion für interne Tests freigegeben, bevor sie die Endbenutzer erreicht. Während des Dogfoodings wird die Funktion in der Produktion zur Verfügung gestellt, jedoch nur für interne Benutzer (Mitarbeiter, Teammitglieder usw.). Auf diese Weise können wir mithilfe realer Produktionsdaten testen und validieren, ob die neue Funktion wie erwartet funktioniert, ohne externe Benutzer zu beeinträchtigen.


Beim Dogfooding gibt es unterschiedliche Strategien. Für einen einfacheren Überblick könnten wir sie in zwei größere Bereiche gruppieren:

  1. Vollständiges Artefakt-Dogfooding : Dies ist beispielsweise bei iOS-/Android-Apps üblich, wo wir über integrierte Tools verfügen, um eine neue App-Version für bestimmte Benutzer freizugeben und diese Version dann für die breite Öffentlichkeit in den Stores verfügbar zu machen.
  2. Selektives Hundefutter : Manchmal ist es nicht möglich (oder sogar erwünscht), das gesamte Artefakt mit Dogfood zu füttern, aber wir können das Dogfooding trotzdem auf der Grundlage spezifischer Benutzerinformationen zulassen. Nehmen wir zum Beispiel an, wir können Mitarbeiter identifizieren, indem wir einige Daten kreuzen. Die Anwendung könnte dann so konfiguriert werden, dass sie eine bestimmte Funktion aktiviert/deaktiviert, indem sie diese Daten überprüft und den Benutzer zum gewünschten Verhalten verleitet. Die Anwendung enthält dann beide Funktionen, allerdings wären nur einige Nutzer von der neuen Änderung betroffen. Wir werden in den nächsten Themen auf einige dieser Konzepte zurückkommen.

Kanarische Veröffentlichung

Canary Release ist ein Veröffentlichungsprozess, bei dem die Änderungen nicht in der Produktion auf einmal auf allen Servern bereitgestellt werden, sondern die Änderungen einer kleinen Teilmenge von ihnen zur Verfügung gestellt und für einige Zeit überwacht werden. Erst nachdem bestätigt wurde, dass die Änderung stabil ist, wird sie in die Produktionsumgebung übertragen.


Kanarische Veröffentlichung


Dies ist eines der leistungsstärksten Tools zum Testen neuer Funktionen und riskanter Änderungen und verringert so die Wahrscheinlichkeit, dass in der Produktion etwas kaputt geht. Indem wir die Änderung an einer Gruppe von Benutzern testen, können wir den Rollout-Prozess stoppen/rückgängig machen, wenn ein Problem erkannt wird, und so die Auswirkungen auf die meisten Benutzer vermeiden.

Blaugrüne Bereitstellung

Blue Green Deployment, eine DevOps-Praxis, zielt darauf ab, Ausfallzeiten zu verhindern, indem zwei Servercluster (Blue und Green) verwendet und der Produktionsverkehr zwischen ihnen umgeschaltet wird. Während des Feature-Rollouts werden Änderungen an einem Satz (Grün) veröffentlicht, während der andere (Blau) unverändert bleibt. Bei Problemen kann der Datenverkehr schnell auf die Blue-Server zurückgeführt werden, da diese mit der Vorgängerversion weiterlaufen.


#Blue Green-Bereitstellung

Blue Green Deployment wird oft mit dem Canary Release verglichen, das wir zuvor besprochen haben. Wir werden in dieser Diskussion nicht näher auf die Details eingehen, aber es ist wichtig, dies zu erwähnen, um uns bei der Entscheidung zu helfen, welche Tools für unsere Arbeit besser geeignet sind.

Kill-Schalter und Funktionsumschaltung

Notausschalter haben ihren Ursprung nicht im Kontext der Softwareentwicklung, und der beste Weg, ihre Verwendung zu verstehen, besteht darin, auf die ursprüngliche Absicht und das ursprüngliche Design zurückzublicken. Bei Maschinen, die in der Industrie eingesetzt werden, handelt es sich bei Kill-Schaltern um Sicherheitsmechanismen, die diese durch eine sehr einfache Interaktion (normalerweise einen einfachen Knopf oder einen Ein-/Ausschalter) so schnell wie möglich abschalten. Sie existieren für Notsituationen, um zu verhindern, dass ein Vorfall (z. B. eine Maschinenstörung) einen noch schlimmeren Vorfall (Verletzungen oder Tod) verursacht.


In der Softwareentwicklung dienen Kill-Switches einem ähnlichen Zweck: Wir akzeptieren den Verlust (oder das Beenden) einer bestimmten Funktion, um das System am Laufen zu halten. Bei der Implementierung handelt es sich auf hoher Ebene um eine Bedingungsprüfung (siehe Codeausschnitt unten), die normalerweise am Einstiegspunkt einer bestimmten Änderung oder Funktion hinzugefügt wird.


 if (feature_is_enabled('feature_x')) {xNewBehaviour();} else {xOldBehaviour();}


Nehmen wir zum Beispiel an, wir versenden eine Migration auf eine neue Drittanbieter-API. In den Tests ist alles in Ordnung, im Canary-Release stabil und dann wird die Änderung zu 100 % in die Produktion ausgerollt. Nach einiger Zeit fängt die neue API an, mit der Menge zu kämpfen und Anfragen schlagen fehl (erinnern Sie sich an die technischen Kennzahlen?). Da wir über einen Kill-Switch verfügen, können API-Anfragen sofort auf die alte API zurückgesetzt werden, und wir müssen nicht auf eine frühere Version zurückgreifen oder schnell einen Hotfix ausliefern.


Technisch gesehen sind Kill-Switches eigentlich ein besonderer Anwendungsfall von Feature-Toggles (auch bekannt als Feature-Flags). Während wir uns mit diesem Thema befassen, ist es erwähnenswert, einen weiteren großen Vorteil der Funktionsumschaltung zu erwähnen: die Ermöglichung einer Trunk-basierten Entwicklung. Dank der Funktionsumschaltung kann neuer Code sicher in die Produktion übernommen werden, auch wenn er unvollständig oder noch nicht getestet ist.

Altes Verhalten zugänglich halten

Der oben beispielhaft dargestellte Code hat einige von uns wahrscheinlich dazu gebracht, sich zu fragen, ob das tatsächlich ein gutes Muster ist, bei dem sowohl alte als auch neue Verhaltensweisen gleichzeitig in der Anwendung leben. Ich stimme zu, dass dies wahrscheinlich nicht der Endzustand ist, den wir für unsere Codebasis wünschen, da sonst jedes einzelne Codestück von if/else-Klauseln umgeben wäre, was den Code in kürzester Zeit unlesbar machen würde.


Allerdings sollten wir das alte Verhalten nicht immer überstürzt löschen. Ja, es ist sehr verlockend, den Code zu bereinigen, sobald er nicht mehr verwendet wird, und technische Schulden zu vermeiden. Es ist aber auch in Ordnung, die Funktion für einige Zeit dort zu belassen und die Funktion umzuschalten. Manchmal kann es eine Weile dauern, bis die neue Funktion stabilisiert ist, und eine Backup-Option ist ein sicherer Mechanismus für den Fall, dass wir darauf zurückgreifen müssen, auch wenn es nur für kurze Zeit ist.


Der Lebenszyklus jeder Veröffentlichung ist unterschiedlich und es empfiehlt sich, den Überblick darüber zu behalten, wann ein guter Zeitpunkt ist, alten Code loszuwerden. Wenn Sie den Code sauber halten und den Wartungsaufwand reduzieren, können Sie die umgekehrte Situation vermeiden, in der die Funktion zwar im Code deaktiviert ist, sie aber wahrscheinlich nicht mehr funktioniert, wenn man bedenkt, wie lange seit der Deaktivierung vergangen ist.

Schattenprüfung

Eine meiner Lieblingstechniken zum Implementieren sicherer Änderungen ist das sogenannte Schattentesten oder Schattenmodus. Es besteht darin, sowohl alte als auch neue Verhaltensweisen auszuführen, um die Ergebnisse zu vergleichen, aber gegebenenfalls einige der Nebenwirkungen des neuen Verhaltens zu deaktivieren. Schauen wir uns dieses einfache Beispiel an:


 int sum(int a, int b) {int currentResult = currentMathLib.sum(a, b);int newResult = newMathLib.sum(a, b);logDivergences(a, b, currentResult, newResult);return currentResult;}void logSumDivergences(int a, int b, int currentResult, int newResult) {if (currentResult != newResult) {logger.warn(      'Divergence detected when executing {0} + {1}: {2} != {3}',a, b, currentResult, newResult);}}


Obwohl beide Summenoperationen ausgeführt werden, dient die neue nur dem Vergleich und der Protokollierung von Abweichungen. Diese Technik ist besonders nützlich, um komplexe Systemänderungen zu überwachen, und wir erwarten eine gewisse Gleichheit zwischen dem alten und dem neuen Verhalten. Ein weiterer großartiger Anwendungsfall ist, wenn wir Änderungen an Produkten vornehmen müssen, mit denen wir nicht sehr vertraut sind, oder wenn wir nicht genau wissen, welche Grenzfälle von der beabsichtigten Änderung betroffen sein könnten.


In komplexeren Szenarien müssen wir möglicherweise einige Nebenwirkungen deaktivieren, bevor wir Schattentests aktivieren. Nehmen wir zum Beispiel an, wir implementieren eine neue Backend-API, um Benutzer anzumelden und in der Datenbank zu speichern und die Benutzer-ID zurückzugeben. Wir könnten sogar eine Schattendatenbank einrichten, um den gesamten Prozess auszuführen, aber es ist definitiv keine gute Idee, die E-Mail „Registrierung erfolgreich“ zweimal zu senden, eine für jede Backend-API. Auch im selben Beispiel würden wir eine tiefere Vergleichslogik benötigen, da ein einfacher Vergleich der zurückgegebenen Benutzer-IDs nicht sehr nützlich wäre.


Schließlich ist es wichtig zu verstehen, was überwacht und getestet werden muss und welche Kriterien angewendet werden, wenn die Parität nicht erreicht wird. In einigen kritischen Szenarien müssen wir die Schattentests wiederholen, bis die Ergebnisse genau gleich sind. In anderen Fällen kann es in Ordnung sein, einen gewissen Prozentsatz an Abweichung zu haben, wenn die neue Implementierung zusätzliche Vorteile bietet, die den Verlust überwiegen.

Protokolle

Selbst mit robusten Schutzmaßnahmen können Systeme ins Stocken geraten. Wenn es passiert, müssen wir in der Lage sein, den Vorfall mit der richtigen Detailtiefe zu verstehen, andernfalls kann es äußerst schwierig sein, eine effiziente Lösung zu finden. Hier kommen Protokolle zum Einsatz, um den Tag zu retten.


Obwohl die Protokollierung kein neues Konzept ist und es viele einfach zu implementierende Lösungen gibt, ist die Sicherstellung effektiver Protokolle eine Herausforderung. Oft sind Protokolle unklar, übermäßig komplex, fehlen oder sind mit irrelevanten Einträgen überflutet, was die Fehlerbehebung erschwert. Protokolle dienen jedoch nicht nur der Behebung von Problemen. Eine ordnungsgemäße Protokollierung hilft bei der Überprüfung der Wirksamkeit neuer Funktionen und Änderungen. Durch das Sampling von Protokolleinträgen kann man Benutzerreisen nachverfolgen und bestätigen, dass Systeme wie vorgesehen funktionieren.

Abschließende Gedanken

Der Versand von Code an die Produktion ist manchmal gefährlich, aber wir haben viele Strategien, um den Prozess viel sicherer zu machen. Auch wenn wir ein Problem identifizieren, ist es wichtig zu wissen, was akzeptabel ist und was nicht. Nicht alle Fehler müssen zu einem Rollback führen. Was ist, wenn wir versuchen, eine schwerwiegende Sicherheitslücke zu beheben oder eine neue Verordnung einzuhalten? Es ist sehr wichtig, klare Kriterien zu haben und zu verstehen, wie kritisch die Änderung ist, um zu bestimmen, wann im Falle von Problemen ein Abbruch oder eine Fortsetzung erfolgen sollte. Um noch einmal auf den Anfang zurückzukommen: Die wichtigsten Kennzahlen sind dazu da, uns im Entscheidungsprozess zu helfen.


Sichere Landung, alle zusammen!