Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Lassen Sie uns besprechen, warum CI-Tools und CI etwas ganz Unterschiedliches sind.

Welches Problem soll CI lösen, woher kam die Idee, welche letzten Bestätigungen gibt es, dass es funktioniert, und wie erkennen Sie, dass Sie tatsächlich eine Praxis haben und nicht nur ein installiertes Jenkins.

Die Idee, einen Vortrag über Continuous Integration zu halten, entstand vor einem Jahr, als ich zu Vorstellungsgesprächen ging und nach einem Job suchte. Ich sprach mit 10-15 Unternehmen, von denen nur eines in der Lage war, verständlich zu erklären, was CI ist, und zu erläutern, wie sie begriffen haben, dass sie es nicht hatten. Die anderen redeten wirres Zeug über Jenkins 🙂 Nun, wir haben Jenkins, es macht Builds, CI! Für den Vortrag werde ich versuchen zu erklären, was Continuous Integration tatsächlich ist und warum Jenkins und ähnliche Werkzeuge so wenig damit zu tun haben.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Und was fällt den Leuten normalerweise ein, wenn sie das Wort CI hören? Den meisten wird Jenkins, Gitlab CI, Travis usw. einfallen.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Selbst wenn wir googeln, wird uns eine Liste dieser Tools angezeigt.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Wenn man fragt, was CI ist, dann erzählen sie Ihnen sofort nach der Aufzählung der Werkzeuge, dass CI bedeutet, dass beim Pull Request von einem Commit ein Build und Testdurchlauf erfolgt.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Continuous Integration handelt nicht von Werkzeugen, nicht von Builds mit Tests im Branch! Continuous Integration ist eine Praxis der sehr häufigen Integration neuen Codes, und dafür ist es überhaupt nicht notwendig, Jenkins, GitLab usw. aufzubauen.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Bevor wir uns anschauen, wie ein vollständiges CI aussieht, lassen Sie uns zunächst in den Kontext der Leute eintauchen, die das erfunden haben, und das Schmerzgefühl nachvollziehen, das sie zu lösen versuchten.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Sie wollten das Problem der gemeinsamen Arbeit im Team lösen!

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Schauen wir uns an, mit welchen Schwierigkeiten Entwickler bei der Teamarbeit konfrontiert sind. Angenommen, wir haben ein Projekt, den Master-Branch in Git und zwei Entwickler.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Und sie fangen an zu arbeiten, wie es seit langem üblich ist. Sie nehmen eine Aufgabe im JIRA, erstellen einen Feature-Branch und schreiben Code.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Einer hat die Funktion schneller fertiggestellt und hat in den Master gemergt.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Der andere benötigte mehr Zeit, er hat später gemergt und erhielt einen Konflikt. Jetzt verbringt der Entwickler, anstatt die notwendigen geschäftlichen Funktionen zu schreiben, seine Zeit und Energie mit der Behebung von Konflikten.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Je komplizierter es ist, Ihr Feature mit dem Haupt-Repository zu verbinden, desto mehr Zeit investieren wir dafür. Und das ist noch ein relativ einfaches Beispiel. Das ist ein Beispiel, bei dem es nur zwei Entwickler gibt. Stellen Sie sich vor, wenn in einem Unternehmen 10, 15 oder 100 Leute in ein und dasselbe Repository schreiben. Sie werden verrückt, all diese Konflikte zu lösen.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Es gibt einen etwas anderen Fall. Wir haben einen Haupt-Branch und mehrere Entwickler, die etwas tun.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Sie haben jeweils einen Branch erstellt.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Einer hat seine Änderungen gemergt, alles gut, Aufgabe abgegeben.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Der zweite Entwickler hat in der Zwischenzeit seine Aufgabe abgeschlossen. Angenommen, er hat sie zur Überprüfung eingereicht. In vielen Unternehmen gibt es die Praxis – die Überprüfung. Einerseits ist diese Praxis gut und nützlich, andererseits bremst sie uns oft. Wir wollen nicht darauf eingehen, aber das ist ein hervorragendes Beispiel dafür, wohin eine fehlgeleitete Überprüfung führen kann. Sie haben einen Pull-Request zur Überprüfung eingereicht. Der Entwickler hat nichts mehr zu tun. Was fängt er an zu tun? Er beginnt, andere Aufgaben zu übernehmen.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

In der Zwischenzeit hat der zweite Entwickler noch etwas gemacht.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Der erste hat die dritte Aufgabe erledigt.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Und nach einer gewissen Zeit wurde sein Review bearbeitet und er versucht, sich zu mergen. Und was passiert? Er gerät in eine riesige Menge an Konflikten. Warum? Weil, während sein Pull-Request zur Überprüfung anhängig war, sich im Code bereits vieles geändert hat.

Neben der Konfliktgeschichte gibt es auch eine Kommunikationsgeschichte. Solange Ihr Branch zur Überprüfung anhängt, während er auf etwas wartet und Sie lange an einem Feature arbeiten, hören Sie auf zu verfolgen, was sich in der Codebasis Ihres Dienstes noch ändert. Möglicherweise haben andere das, was Sie jetzt zu lösen versuchen, bereits gestern gelöst, und Sie könnten eine Methode wiederverwenden. Aber das werden Sie nicht sehen, weil Sie immer mit einem veralteten Branch arbeiten. Und dieser veraltete Branch führt immer dazu, dass Sie einen Merge-Konflikt lösen müssen.

Es ergibt sich also, dass wenn wir im Team arbeiten, d. h. wenn nicht nur eine Person im Repository arbeitet, sondern 5-10 Personen, desto länger wir unseren Code nicht in den Haupt-Branch einfügen, desto mehr leiden wir darunter, dass wir letztendlich etwas mergen müssen. Und je mehr Konflikte wir haben und je älter die Version ist, mit der wir arbeiten, desto mehr Probleme haben wir.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Gemeinsam etwas zu tun ist schmerzhaft! Wir behindern uns immer gegenseitig.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Dieses Problem wurde vor über 20 Jahren erkannt. Die erste Erwähnung der Continuous Integration-Praktik fand ich im Extreme Programming.

Extreme Programming ist das erste Agile Framework. Die Seite erschien im Jahr 1996. Die Idee war, bestimmte Programmier- und Planungspraktiken zu verwenden, um die Entwicklung so flexibel wie möglich zu gestalten, damit wir schneller auf Änderungen und Anforderungen unserer Kunden reagieren können. Vor 24 Jahren begannen sie, mit der Herausforderung umzugehen, dass, wenn man etwas sehr lange und isoliert macht, man dafür mehr Zeit aufwendet, weil es zu Konflikten kommt.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Jetzt werden wir den Begriff „Continuous Integration“ Wort für Wort durchgehen. Übersetzt man es wörtlich, bedeutet es kontinuierliche Integration. Aber wie kontinuierlich es wirklich ist, ist unklar; es ist tatsächlich sehr unterbrochen. Auch wie viel Integration darin steckt, ist nicht ganz offensichtlich.

Und deshalb bringe ich Ihnen jetzt Zitate aus dem Extreme Programming. Wir werden beide Begriffe getrennt analysieren.

Integration – wie ich bereits sagte, streben wir an, dass jeder Ingenieur mit der aktuellsten Version des Codes arbeitet, sodass er seinen Code so oft wie möglich in den Hauptzweig einfügt und dass es kleine Zweige sind. Denn wenn sie groß sind, können wir leicht eine Woche mit Merge-Konflikten stecken bleiben. Besonders, wenn wir einen langen Entwicklungszyklus wie Waterfall haben, bei dem ein Entwickler einen Monat damit verbringt, eine riesige Funktion zu entwickeln. Und während der Integrationsphase kann er sehr lange stecken bleiben.

Integration – das ist, wenn wir unseren Branch nehmen und ihn mit dem Master integrieren, wir ihn zusammenführen. Es gibt einen ultimativen Ansatz, bei dem wir als Transbase-Entwickler anstreben, direkt im Master zu schreiben, ohne unnötige Branches.

Zusammengefasst ist Integration das Übernehmen des eigenen Codes und das Bereitstellen im Master.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Was bedeutet hier das Wort „continuous“, was wird unter Kontinuität verstanden? Die Praxis sieht vor, dass der Entwickler seinen Code so schnell wie möglich integriert. Das ist sein Ziel bei jeder Aufgabe – dafür zu sorgen, dass sein Code so schnell wie möglich in den Master kommt. In einer idealen Welt würden die Entwickler dies alle paar Stunden tun. Das heißt, du nimmst dir eine kleine Aufgabe, merge sie in den Master. Alles läuft wunderbar. Darauf strebst du hin. Und das muss kontinuierlich geschehen. Sobald du etwas gemacht hast, drückst du es sofort in den Master.

Und der Entwickler, der etwas macht, ist dafür verantwortlich, dass es funktioniert und nichts kaputt gemacht wird. Hier kommt normalerweise das Thema Tests ins Spiel. Wir möchten einige Tests für unser Commit, für unser Merge durchführen, um sicherzustellen, dass es funktioniert. Hierbei kann Ihnen Jenkins wirklich helfen.

Aber bei den Geschichten: Lass uns die Änderungen klein halten, lass uns die Aufgaben klein halten, lass uns die Aufgabe erledigen und sie sofort versuchen, in den Master zu mergen – da helfen dir keine Jenkins. Denn Jenkins hilft dir ausschließlich, die Tests auszuführen.

Du kannst auch ohne sie auskommen. Das wird dir nicht schaden. Denn das Ziel der Praxis ist es, so oft wie möglich zu mergen, um nicht viel Zeit mit zukünftigen Konflikten zu verschwenden.

Stell dir vor, wir haben das Jahr 2020 aus irgendeinem Grund ohne Internet. Und wir arbeiten lokal. Wir haben kein Jenkins. Das ist in Ordnung. Du kannst immer noch einen lokalen Branch erstellen. Du hast dort einen bestimmten Code geschrieben. Hast die Aufgabe in 3-4 Stunden erledigt. Bist zu Master gewechselt, hast git pull gemacht, und hast deinen Branch dort gemerged. Fertig. Wenn du das oft machst – herzlichen Glückwunsch, du hast Continuous Integration!

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Welche Beweise gibt es in der modernen Welt dafür, dass es sich lohnt, Kräfte darauf zu verwenden? Denn im Großen und Ganzen ist es kompliziert. Wenn du versuchst, so zu arbeiten, wirst du feststellen, dass du jetzt irgendwie mit der Planung konfrontiert wirst und mehr Zeit mit der Dekomposition von Aufgaben verbringen musst. Denn wenn du man… machst, wirst du nicht schnell mergen können und als Ergebnis in Schwierigkeiten geraten. Dann gibt es keine Praxis mehr.

Und das wird teuer. Ab morgen direkt mit Continuous Integration zu arbeiten, wird nicht möglich sein. Ihr werdet alle sehr lange brauchen, um euch daran zu gewöhnen, die Aufgaben zu dekomponieren, sehr lange brauchen, um euch daran zu gewöhnen, die Review-Praxis zu ändern, falls ihr diese habt. Denn unser Ziel ist es, dass es heute gemerged wird. Wenn ihr jedoch drei Tage für die Review braucht, habt ihr Probleme und es funktioniert nicht mit Continuous Integration.

Aber gibt es irgendwelche aktuellen Beweise, die uns direkt jetzt sagen, dass es sinnvoll ist, in diese Praxis zu investieren?

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Das Erste, was mir in den Sinn kam, war der State of DevOps. Diese Studie wird seit 7 Jahren von einem Team durchgeführt. Momentan machen sie das als unabhängige Organisation, aber unter Google.

Und ihre Studie im Jahr 2018 zeigte eine Korrelation zwischen Unternehmen, die kurze Branches verwenden, die schnell und häufig integriert werden. Diese Unternehmen haben viel bessere IT-Leistungskennzahlen.

Was sind das für Kennzahlen? Es handelt sich um 4 Metriken, die sie in ihren Umfragen von allen Unternehmen erfassen: Deployment-Frequenz, Vorlaufzeit für Änderungen, Wiederherstellungszeit des Dienstes, Änderungsfehlerrate.

Und erstens gibt es diese Korrelation, wir wissen, dass Unternehmen, die häufig mergen, viel bessere Metriken haben. Sie haben die Unternehmen in mehrere Kategorien unterteilt: langsame Unternehmen, die etwas langsam produzieren, Mittelmäßige, Hochleister und die Elite. Die Elite sind Netflix, Amazon, die super schnell sind, alles schnell, schön und qualitativ hochwertig machen.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Die zweite Geschichte, die vor einem Monat passiert ist. Im Technology Radar erschien ein wunderbarer Artikel über Gitflow. Gitflow unterscheidet sich von allen anderen dadurch, dass seine Branches lange leben. Es gibt Release-Branches, die lange leben, und Feature-Branches, die ebenfalls lange leben. Diese Praxis wurde im Technology Radar in den HOLD-Status versetzt. Warum? Weil die Leute mit den Schwierigkeiten der Integration konfrontiert sind.

Wenn deine Branch sehr lange lebt, gerät sie in die Irre und wird veraltet, wir beginnen mehr Zeit damit zu verbringen, irgendeine Änderung zu integrieren.

Und kürzlich sagte der Autor von Gitflow, dass, wenn Sie auf Continuous Integration abzielen und möchten, dass Sie so oft wie möglich integrieren, Gitflow eine schlechte Idee ist. Er fügte in einem separaten Artikel hinzu, dass, wenn Sie ein Backend haben, auf das Sie hinarbeiten können, Gitflow für Sie überflüssig ist, da es Sie verlangsamen und Integrationsprobleme verursachen kann.

Das bedeutet jedoch nicht, dass Gitflow schlecht ist und dass man es nicht nutzen sollte. Es ist für andere Fälle geeignet. Zum Beispiel, wenn Sie mehrere Versionen eines Dienstes oder einer Anwendung unterstützen müssen, d. h. wenn Sie über einen längeren Zeitraum hinweg Support bieten müssen.

Aber wenn Sie mit Menschen sprechen, die solche Dienste unterstützen, werden Sie viel darüber hören, dass diese Version 3.2 gewesen ist, die vor 4 Monaten war, und dass dieser Fix nicht enthalten war. Jetzt muss man viele Änderungen vornehmen, um ihn zu integrieren. Und schon stecken sie wieder fest und kämpfen eine Woche lang darum, eine neue Funktion zu mergen.

Wie Alexander Kowalew richtig im Chat bemerkte, ist Korrelation nicht gleich Ursache und Wirkung. Das ist richtig. Das heißt, es gibt keine direkte Verbindung, dass, wenn Sie Continuous Integration haben, all Ihre Metriken großartig sind. Aber es gibt eine positive Korrelation, dass, wenn das eine zutrifft, das andere wahrscheinlich auch zutrifft. Es ist keine Tatsache, aber höchstwahrscheinlich. Es ist nur eine Korrelation.

Continuous Integration als Praxis, nicht Jenkins. Andrei Alexandrow

Es scheint, als ob wir bereits etwas tun und mergen, aber wie können wir feststellen, dass wir tatsächlich Continuous Integration haben und genügend oft mergen?

Jez Humble ist der Autor des Handbuchs, von Accelerate, der Website für Continuous Delivery und des Buches 'Continuous Delivery'. Er schlägt diesen Test vor:

  • Der Code eines Ingenieurs gelangt täglich in den Master.
  • Bei jedem Commit führen Sie Unit-Tests durch.
  • Der Build im Master ist ausgefallen, und er wurde innerhalb von etwa 10 Minuten repariert.

Er schlägt vor, diesen Test zu verwenden, um sicherzustellen, dass Sie die Praxis tatsächlich haben.

Das Letzte finde ich ein wenig umstritten. Das heißt, wenn Sie in der Lage sind, innerhalb von 10 Minuten zu reparieren, haben Sie Continuous Integration, was meiner Meinung nach ein wenig seltsam klingt, aber es macht Sinn. Warum? Weil, wenn Sie häufig mergen, bedeutet das, dass Ihre Änderungen klein sind. Wenn eine kleine Änderung dazu führt, dass Ihr Master-Build kaputt geht, werden Sie schnell einen Fehler finden können, weil die Änderung geringfügig ist. Nehmen wir an, Sie hatten ein kleines Mergen, bei dem sich 20-30 Zeilen geändert haben. Dementsprechend können Sie schnell verstehen, was das Problem war, weil die Änderungen winzig sind und Sie ein sehr kleines Suchfeld für das Problem haben.

Und selbst wenn unser Prod nach dem Release zusammenbricht, wenn wir die Continuous-Integration-Praxis haben, wird es uns viel einfacher fallen zu handeln, weil die Änderungen gering sind. Ja, das wird die Planung betreffen. Es wird schmerzhaft sein. Und wahrscheinlich ist das Schwierigste an dieser Praxis, sich daran zu gewöhnen, Aufgaben zu zerlegen, d.h. wie man etwas nimmt und es in ein paar Stunden fertigstellt und dabei eine Überprüfung durchläuft, wenn Sie eine haben. Die Überprüfung ist ein separates Übel.

Unit-Tests sind einfach ein Helfer, der Ihnen hilft zu verstehen, ob Ihre Integration erfolgreich war, ob nichts kaputt gegangen ist. Meiner Meinung nach ist das nicht ganz zwingend erforderlich, denn der Sinn der Praxis liegt nicht darin.

Das ist eine kurze Einführung in Continuous Integration. Das ist alles, was es in dieser Praxis gibt. Ich bin bereit für Fragen.

Zusammenfassend möchte ich noch einmal die Ergebnisse zusammenfassen:

  • Continuous Integration ist nicht Jenkins, es ist nicht Gitlab.
  • Es ist kein Werkzeug, es ist eine Praxis, bei der wir unseren Code so oft wie möglich in den Master mergen.
  • Wir tun dies, um enorme Schmerzen zu vermeiden, die in Zukunft durch Merges entstehen, d.h. wir erfahren jetzt einen kleinen Schmerz, um in Zukunft keinen großen zu empfinden. Darin liegt der ganze Sinn.
  • Von der Seite her passiert die Kommunikation durch den Code, aber ich sehe das sehr selten, obwohl es auch dafür gedacht ist.

Fragen

Was ist mit Aufgaben, die nicht zerlegt werden können?

Zerlegen. Was ist das Problem? Können Sie ein Beispiel geben, wo es eine Aufgabe gibt, die sich nicht zerlegen lässt?

Es gibt solche Aufgaben, die von „überhaupt nicht“ nicht zerlegt werden können, zum Beispiel solche, die sehr tiefes Fachwissen erfordern und die tatsächlich über einen Monat bis zu einem bestimmten akzeptablen Ergebnis bearbeitet werden müssen.

Wenn ich dich richtig verstanden habe, gibt es eine große und komplexe Aufgabe, deren Ergebnis erst in einem Monat sichtbar sein wird.

Ja, das ist korrekt. Ja, das Ergebnis kann frühestens in einem Monat bewertet werden.

Gut. Insgesamt ist das kein Problem. Warum? Weil wir in diesem Fall, wenn wir über Branches sprechen, nicht über eine Branch mit einer Funktion reden. Funktionen können groß und komplex sein. Sie können viele Komponenten betreffen. Und vielleicht können wir sie nicht vollständig in einer Branch umsetzen. Das ist in Ordnung. Wir müssen diese Geschichte einfach aufteilen. Wenn die Funktion bis zum Ende nicht fertig ist, bedeutet das nicht, dass bestimmte Teile ihres Codes nicht zusammengeführt werden können. Du hast zum Beispiel eine Migration hinzugefügt und innerhalb der Funktion gibt es bestimmte Phasen. Du hast, sagen wir, eine Phase - die Migration zu machen, eine neue Methode hinzuzufügen. Und diese Dinge kannst du bereits täglich zusammenführen.

Gut. Was ist der Sinn davon?

Was bringt es, kleine Dinge täglich zusammenzuführen?

Ja.

Wenn sie dir etwas kaputt gemacht haben, siehst du das sofort. Du hast ein kleines Stück, das etwas kaputt gemacht hat, und es ist einfacher, das zu reparieren. Der Sinn ist, dass es viel einfacher ist, jetzt ein kleines Stück zusammenzuführen, als in ein paar Wochen etwas Großes zusammenzuführen. Und ein dritter Grund ist, dass andere Ingenieure mit der bereits aktuellen Version des Codes arbeiten werden. Sie werden sehen, dass hier einige Migrationen hinzugefügt wurden und dort eine Methode erschien, die sie möglicherweise auch nutzen möchten. Jeder wird sehen, was in deinem Code passiert. Genau aus diesen drei Gründen wird diese Praxis durchgeführt.

Danke, die Frage ist damit geklärt!

(Oleg Soroka) Darf ich noch etwas hinzufügen? Du hast alles richtig gesagt, ich möchte nur einen Satz ergänzen.

Okay.

Bei Continuous Integration wird der Code nicht zusammengeführt, wenn die Funktion vollständig bereit ist, sondern wenn der Build nicht mehr fehlschlägt. Und ihr könnt so oft ihr wollt täglich in den Master committen. Ein zweiter Aspekt - wenn ihr aus irgendeinem Grund die monatliche Aufgabe nicht in Aufgaben von mindestens drei Tagen aufteilen könnt, ich schweige von drei Stunden, dann habt ihr ein großes Problem. Und die Tatsache, dass ihr keine Continuous Integration habt - das ist das geringste dieser Probleme. Das bedeutet, dass ihr Probleme mit der Architektur habt und eure Ingenieurpraktiken gleich null sind. Denn selbst wenn es sich um Forschung handelt, muss das immer noch in Form von Hypothesen oder Zyklen strukturiert werden.

Wir haben über 4 Metriken gesprochen, die erfolgreiche Unternehmen von den weniger erfolgreichen unterscheiden. Man muss erst einmal zu diesen 4 Metriken kommen. Wenn du durchschnittlich einen Monat für eine Aufgabe brauchst, würde ich mich zuerst auf diese Metrik konzentrieren. Ich würde sie zunächst auf 3 Tage reduzieren. Und danach würde ich anfangen, über Continuous nachzudenken.

Habe ich dich richtig verstanden, dass du denkst, dass es im Allgemeinen keinen Sinn macht, in Ingenieurlösungen zu investieren, wenn du für jede Aufgabe einen Monat benötigst?

Du hast Continuous Integration. Und da gibt es das Thema, dass du innerhalb von 10 Minuten entweder eine Korrektur übernimmst oder zurücksetzt. Stell dir vor, du hast es ausgeführt. Angenommen, du hast sogar ein Continuous Deployment, du hast es auf Prod ausgeführt und hast erst danach bemerkt, dass etwas nicht stimmt. Und du musst es zurücksetzen, aber deine Datenbankmigration hat bereits stattgefunden. Deine Datenbankstruktur ist schon auf die nächste Version, und darüber hinaus wurde auch ein Backup durchgeführt, in das bereits Daten geschrieben wurden.

Und was für eine Alternative hast du? Wenn du den Code zurücksetzt, kann er mit dieser aktualisierten Datenbank nicht mehr funktionieren.

Die Datenbank bewegt sich nur vorwärts, ja.

Bei Leuten mit schlechter Ingenieurausbildung haben sie wahrscheinlich auch kein dickes Buch über ... gelesen. Was macht man mit Backups? Wenn du aus einem Backup wiederherstellst, verlierst du die Daten, die sich in der Zwischenzeit angesammelt haben. Zum Beispiel hast du drei Stunden mit der neuen Version der Datenbank gearbeitet, in die sich Benutzer registriert haben. Du greifst auf das alte Backup zurück, weil mit der neuen Version die Struktur nicht funktioniert, folglich hast du diese Benutzer verloren. Und sie sind unzufrieden, sie beschweren sich.

Um ein umfassendes Spektrum an Praktiken zu beherrschen, die Continuous Integration und Continuous Delivery unterstützen, reicht es nicht aus, einfach nur zu lernen, wie man schreibt …. Erstens könnte es sehr viele werden, was unpraktisch wäre. Außerdem gibt es viele andere Praktiken, zum Beispiel Scientific. Es gibt eine Praxis, die von GitHub zu seiner Zeit populär gemacht wurde. Dabei wird gleichzeitig alter und neuer Code ausgeführt. Es handelt sich um eine unvollendete Funktion, die jedoch einen Wert zurückgeben kann: entweder als Funktion oder als REST API. Du führst sowohl den neuen als auch den alten Code aus und vergleichst die Unterschiede zwischen ihnen. Wenn es Unterschiede gibt, protokollierst du dieses Ereignis. So weißt du, dass deine neue Funktion bereit ist, anstelle der alten bereitgestellt zu werden, wenn es während eines bestimmten Zeitraums keine Abweichungen zwischen diesen beiden gibt.

Es gibt Hunderte solcher Praktiken. Ich würde vorschlagen, mit transbase development zu beginnen. Es ist nicht zu 100 % auf Continuous Integration ausgerichtet, aber die Praktiken sind dieselben, und eins kann ohne das andere nicht gut funktionieren.

Hast du transbase development als Beispiel genannt, wo man Praktiken anschauen kann, oder schlägst du vor, dass die Leute transbase development nutzen?

Schauen, da sie es nicht benutzen können. Um es zu verwenden, muss man viel lesen. Und wenn bei einer Person die Frage auftaucht: „Was soll ich mit einer Funktion machen, die einen Monat dauert?“, bedeutet das, dass sie nicht über transbase development gelesen hat. Ich würde es auch nicht empfehlen. Ich würde vorschlagen, sich ausschließlich darauf zu konzentrieren, wie man große Aufgaben architektonisch korrekt in kleinere aufteilen kann. Das ist die Essenz der Dekomposition.

Dekomposition ist eines der Werkzeuge des Architekten. Zuerst machen wir eine Analyse, dann Dekomposition, dann Synthese und schließlich Integration. So fügen wir alles zusammen. Und um zur Continuous Integration zu kommen, muss man zuerst durch die Dekomposition wachsen. Zu Beginn treten Fragen auf, und wir sprechen bereits über die vierte Phase, d.h. je häufiger man integriert, desto besser. Es ist noch zu früh, um es zu tun; es wäre besser, zuerst das eigene Monolithen zu zerschneiden.

Es müssen ein paar Pfeile und Quadrate in irgendeinem Diagramm gezeichnet werden. Du kannst nicht sagen, dass ich dir jetzt das Architekturdiagramm der neuen Anwendung zeige und ein Quadrat zeige, in dem ein grüner Knopf für die Anwendung ist. Auf jeden Fall wird es mehr Quadrate und Pfeile geben. In jedem Diagramm, das ich gesehen habe, gab es mehr als eines. Die Dekomposition wird sogar auf der Ebene der grafischen Darstellung bereits durchgeführt. Daher können die Quadrate unabhängig gemacht werden. Wenn nicht, dann habe ich große Fragen an den Architekten.

Es gibt eine Frage aus dem Chat: "Wenn das Review zwingend erforderlich ist und lange dauert, einen Tag oder länger?".

Ihr habt Probleme mit der Praxis. Ein Review sollte nicht einen Tag oder länger dauern. Das ist die gleiche Geschichte wie bei der vorherigen Frage, nur etwas milder. Wenn das Review einen Tag dauert, bedeutet das wahrscheinlich, dass es sich um eine sehr große Änderung handelt. Das bedeutet, man sollte kleinere Änderungen vornehmen. In der Transbase-Entwicklung, die Oleg empfohlen hat, gibt es eine Geschichte, die kontinuierliches Review genannt wird. Die Idee dahinter ist, dass wir absichtlich so kleine Pull-Requests machen, weil wir immer wieder und in kleinen Schritten zusammenführen wollen. Daher ändert der Pull-Request eine Abstraktion oder vielleicht 10 Zeilen. Dadurch dauert unser Review nur ein paar Minuten.

Wenn das Review einen Tag oder länger dauert, ist etwas nicht in Ordnung. Erstens könnten Sie Probleme mit der Architektur haben. Oder es handelt sich um ein großes Stück Code, sagen wir 1.000 Zeilen. Oder Ihre Architektur ist so komplex, dass es schwierig ist, sie zu verstehen. Das ist ein Problem, das gelöst werden muss. Vielleicht brauchen Sie überhaupt kein Review. Darüber sollten Sie auch nachdenken. Das Review ist das, was Sie ausbremst. Es hat insgesamt seine Vorteile, aber Sie müssen verstehen, warum Sie es machen. Ist es für Sie eine Möglichkeit, schnell Informationen zu übermitteln, oder ist es eine Möglichkeit, bestimmte Standards zu setzen? Warum brauchen Sie das? Denn Reviews sollten entweder sehr schnell sein oder ganz abgeschafft werden. Das ist wie die Transbase-Entwicklung – eine sehr schöne Geschichte, aber nur für erfahrene Leute.

Was die 4 Metriken betrifft, würde ich trotzdem empfehlen, sie zu erfassen, um zu verstehen, wohin das führt. Sehen Sie sich die Zahlen an, schauen Sie sich das Bild an, wie schlecht es ist.

(Dmitri) Ich bin bereit, dieses Thema mit dir zu diskutieren. Zahlen und Metriken sind toll, Praktiken sind großartig. Aber man muss verstehen, ob das für das Geschäft notwendig ist. Es gibt Unternehmen, die nicht so schnell Änderungsprozesse benötigen. Ich kenne Firmen, in denen man nicht alle 15 Minuten Änderungen vornehmen kann. Und das liegt nicht daran, dass sie schlecht sind. Es ist ein bestimmter Lebenszyklus. Und um Funktionen wie Branches oder Toggles einzuführen, sind tiefgehende Kenntnisse erforderlich.

Es ist kompliziert. Wenn du mehr über die Geschichte von Feature Toggles lesen möchtest, kann ich dir das sehr empfehlen. https://trunkbaseddevelopment.com/. Und es gibt einen hervorragenden Artikel von Martin Fowler über Feature Toggles: über die verschiedenen Typen, Lebenszyklen usw. Feature Toggles sind komplex.

Und du hast die Frage nicht beantwortet: „Braucht man Jenkins oder nicht?“

Jenkins ist in Wahrheit auf keinen Fall notwendig. Wenn ich ehrlich bin, werden dir Werkzeuge wie Jenkins und Gitlab mehr Komfort bieten. Du wirst sehen, ob der Build erfolgreich war oder nicht. Sie können helfen, aber sie werden dir keine Praktiken vermitteln. Sie können dir nur ein kleines Zeichen geben – ok, nicht ok. Und das gilt, wenn du auch Tests schreibst, denn ohne Tests ist es fast sinnlos. Daher ist es nützlich, weil es praktischer ist, aber im Allgemeinen kann man auch ohne leben, man verliert nicht viel.

Das heißt, wenn du Praktiken hast, brauchst du es dann nicht?

Ganz genau. Ich empfehle den Test von Jez Humble. Da habe ich zu dem letzten Punkt eine zwiespältige Meinung. Aber im Allgemeinen, wenn du drei Dinge hast: du mergen ständig, du führst Tests bei Commits im Master aus und reparierst schnell den Build im Master, dann brauchst du vielleicht nicht mehr.

Während wir auf Fragen von den Teilnehmern warten, habe ich eine Frage. Wir haben jetzt über Produktcode gesprochen. Hast du auch für Infrastrukturcode verwendet? Ist das derselbe Code, hat er dieselben Prinzipien und denselben Lebenszyklus, oder gibt es dort andere Lebenszyklen und Prinzipien? Üblicherweise, wenn alle über Continuous Integration und Development sprechen, vergessen sie, dass es auch Infrastrukturcode gibt. Und in letzter Zeit wird es immer mehr davon. Sollten all diese Regeln auch dort gelten?

Es ist nicht nur so, dass es sinnvoll wäre, es wäre großartig, denn es würde das Leben sicher genauso erleichtern. Sobald wir mit Code arbeiten, nicht mit Bash-Skripten, sondern wenn wir richtigen Code haben.

Stopp, stopp, ein Bash-Skript ist auch Code. Fass meine alte Liebe nicht an.

Gut, ich werde deine Erinnerungen nicht treten. Ich habe eine persönliche Abneigung gegen Bash. Es bricht auf hässliche und furchterregende Weise ständig. Und es bricht oft unvorhersehbar, daher mag ich es nicht so sehr. Aber gut, nehmen wir an, du hast Code in Bash. Vielleicht habe ich wirklich keine Ahnung und es gibt vernünftige Test-Frameworks dafür. Ich bin einfach nicht im Thema. Und wir bekommen die gleichen Vorteile.

Sobald wir mit Infrastruktur wie mit Code arbeiten, bekommen wir all die gleichen Probleme wie Entwickler. Vor ein paar Monaten hatte ich eine Situation, in der mir ein Kollege einen Pull-Request mit 1.000 Zeilen Bash geschickt hat. Und du hängst vier Stunden in der Überprüfung fest. Die Probleme sind immer noch die gleichen. Es ist immer noch Code. Und immer noch Teamarbeit. Wir stecken bei Pull-Requests fest und hängen bei den gleichen Merge-Konflikten von Bash fest, zum Beispiel.

Ich schaue mir jetzt sehr aktiv das gesamte Thema an, um die Infrastruktur so schön wie möglich zu programmieren. Ich habe gerade Pulumi in die Infrastruktur eingeführt. Das ist Programmierung pur. Dort sieht es noch ansprechender aus, weil ich alle Möglichkeiten der Programmiersprache habe, d. h. ich habe mit denselben If-Anweisungen auf einfache Weise schöne Toggles erstellt und alles ist gut. Das heißt, meine Änderung ist bereits im Master. Jeder kann sie jetzt sehen. Andere Ingenieure sind darüber informiert. Es hat bereits Einfluss gehabt. Aber es wurde nicht für alle Infrastrukturen aktiviert. Es wurde zum Beispiel für meine Testumgebungen aktiviert. Daher, um deine Frage nochmal zu beantworten, es ist notwendig. Es erleichtert unser Leben als Ingenieure, die mit Code arbeiten, auf die gleiche Weise.

Hat noch jemand Fragen?

Ich habe eine Frage. Ich möchte die Diskussion mit Oleg fortsetzen. Insgesamt denke ich, dass du recht hast, dass, wenn eine Aufgabe einen Monat dauert, du ein Problem mit der Architektur hast, ein Problem mit der Analyse, der Dekomposition, der Planung usw. Aber ich habe das Gefühl, dass, wenn du versuchst, nach Continuous Integration zu leben, du anfängst, die Schmerzen bei der Planung zu beheben, denn du kannst davon nicht mehr weg.

(Oleg) Ja, das ist so. In Bezug auf den Arbeitsaufwand ist diese Praxis mit jeder anderen ernsthaften Praxis vergleichbar, die die Kultur verändert. Das Schwierigste bei der Überwindung sind die Gewohnheiten, insbesondere die schlechten Gewohnheiten. Und wenn es notwendig ist, dass die Gewohnheiten der Umgebung geändert werden: Entwickler, Management, Produktionsleiter, dann erwartet Sie eine Überraschung.

Welche Überraschungen könnte es geben? Angenommen, Sie haben beschlossen, dass Sie die Integration häufiger durchführen werden. Und mit der Integration sind noch andere Dinge verbunden, nehmen wir an, Artefakte. In Ihrem Unternehmen gibt es beispielsweise die Richtlinie, dass jedes Artefakt auf irgendeine Weise in einem System zur Lagerung von Artefakten erfasst werden muss. Und das kostet eine gewisse Zeit. Eine Person muss ein Häkchen setzen, dass sie als Release-Manager dieses Artefakt auf die Betriebsbereitschaft für die Veröffentlichung in der Produktion getestet hat. Wenn das 5-10-15 Minuten dauert, aber Sie einmal pro Woche eine Veröffentlichung machen, dann einmal pro Woche eine halbe Stunde zu investieren – das ist eine geringe Steuer.

Wenn Sie Continuous Integration 10 Mal am Tag durchführen, müssen Sie 10 Mal 30 Minuten multiplizieren. Und das übersteigt die Arbeitszeit dieses Release-Managers. Er ist einfach müde, das zu tun. Es gibt ständige Kosten für bestimmte Praktiken. Und das ist alles.

Und Sie müssen entweder diese Regel aufheben, damit Sie sich nicht mehr mit diesem Unsinn beschäftigen, d.h. Sie weisen nicht mehr manuell einen Grad der Übereinstimmung von etwas mit etwas zu. Sie verlassen sich voll und ganz auf einen automatisierten Testsatz für die Betriebsbereitschaft.

Und wenn Sie von jemandem einen Nachweis benötigen, damit der Chef unterschreibt, und Sie nicht in die Produktion gehen, ohne dass Wanja gesagt hat, dass er es erlaubt usw. – all dieser Unsinn steht den Praktiken im Weg. Denn wenn damit verbundene Aktivitäten als Steuer fungieren, vervielfacht sich alles um das 100-fache. Daher wird eine Veränderung oft nicht von allen positiv aufgenommen. Denn Gewohnheiten sind schwer zu ändern.

Wenn eine Person die gewohnte Arbeit verrichtet, tut sie dies praktisch nicht nachdenken. Die kognitive Belastung beträgt null. Er bearbeitet einfach das Vorhandene, hat bereits eine Checkliste im Kopf, die er tausend Mal durchgegangen ist. Und sobald du kommst und ihm sagst: „Lass uns diese Praxis abschaffen und ab Montag eine neue einführen“, wird dies eine enorme kognitive Belastung für ihn. Und das trifft alle sofort.

Deshalb ist es am einfachsten, obwohl sich diese Eleganz nicht alle leisten können, genau so zu verfahren. Wenn ein neues Projekt gestartet wird, werden oft sofort alle unerprobten Praktiken in dieses Projekt integriert. Solange das Projekt jung ist, riskieren wir nicht viel. Es gibt noch kein Prod, also gibt es nichts, was man ruinieren könnte. Daher kann es als Training genutzt werden. Dieser Ansatz funktioniert. Aber nicht alle Unternehmen haben die Möglichkeit, solche Projekte häufig zu starten. Obwohl es auch etwas seltsam ist, denn derzeit ist die digitale Transformation durchgängig, jeder sollte Experimente durchführen, um mit den Wettbewerbern Schritt zu halten.

Hier kommt man zu dem Punkt, dass man zunächst verstehen muss, was man tun muss. Die Welt ist nicht perfekt, das Prod ist auch nicht perfekt.

Ja, diese Dinge hängen zusammen.

Die Unternehmen haben auch nicht immer das Verständnis, dass sie dorthin gehen sollten.

Es gibt Situationen, in denen keine Veränderungen überhaupt möglich sind. Dies ist der Fall, wenn der Druck auf das Team größer wird. Das Team ist bereits ziemlich erschöpft. Es hat keine Reservezeit für Experimente. Sie arbeiten von morgens bis abends an Features. Und den Führungskräften sind die Features nie genug. Es wird immer mehr verlangt. In einer solchen Situation sind keine Veränderungen möglich. Dem Team kann nur gesagt werden, dass sie morgen genauso arbeiten wie gestern, einfach etwas mehr Features machen müssen. Keinerlei Übergänge zu irgendeiner Praxis sind in diesem Sinne möglich. Dies ist die klassische Situation, in der es keine Zeit gibt, die Axt zu schärfen, man muss die Bäume fällen, also wird mit der stumpfen Axt gearbeitet. Hier gibt es keine einfachen Ratschläge.

(Dmitrij) Ich lese eine Klarstellung aus dem Chat vor: „Aber es ist notwendig, eine umfangreiche Testabdeckung auf verschiedenen Ebenen zu haben. Wie viel Zeit wird für Tests aufgewendet? Irgendwie ist das teuer, nimmt viel Zeit in Anspruch.“

(Oleg) Das ist ein klassisches Missverständnis. Es sollten ausreichend Tests vorhanden sein, damit Sie selbst Vertrauen haben. Continuous Integration ist keine Methode, bei der zuerst 100 % der Tests durchgeführt werden und erst dann beginnen Sie, diese Praxis anzuwenden. Continuous Integration reduziert Ihre kognitive Belastung, weil jede Änderung, die Sie mit eigenen Augen sehen, so offensichtlich ist, dass Sie sofort verstehen, ob sie etwas kaputt macht oder nicht, sogar ohne Tests. Sie können dies im Kopf schnell testen, da es kleine Änderungen sind. Selbst wenn Sie nur manuelle Tester haben, wird es auch für sie einfacher. Sie haben das Release gemacht und gesagt: „Schau mal, ist nichts kaputt?“ Sie haben geprüft und gesagt: „Nein, es ist nichts kaputt.“ Weil der Tester weiß, wo er schauen muss. Ihr Commit ist mit einem Codefragment verknüpft. Und es wird durch ein bestimmtes Verhalten ausgeführt.

Hier hast du natürlich übertrieben.

(Dmitry) Da stimme ich nicht zu. Es gibt die Praxis – Testgetriebene Entwicklung, die gerade davor rettet.

(Oleg) Dazu bin ich noch nicht gekommen. Die erste Illusion ist, dass man genau 100 % Tests schreiben muss oder überhaupt keine Continuous Integration betreiben kann. Das ist nicht wahr. Das sind zwei parallele Praktiken. Und sie hängen nicht direkt voneinander ab. Ihre Testabdeckung sollte optimal sein. Optimal bedeutet, dass Sie selbst sicher sind, dass die Qualität des Masters, die nach dem Commit übrig bleibt, es Ihnen ermöglicht, sicher am Freitagabend im betrunkenen Zustand auf die Schaltfläche „Deploy“ zu klicken. Wie erreichen Sie das? Durch Reviews, durch Abdeckung, durch gutes Monitoring.

Gutes Monitoring ist nicht von Tests zu unterscheiden. Wenn Sie die Tests einmal im Pre-Prod ausführen, überprüfen sie einmal alle Ihre Benutzerszenarien und das war's. Wenn Sie sie jedoch in einem endlosen Zyklus ausführen, haben Sie Ihr erweitertes Monitoring-System, das endlos alles testet – ob es abgestürzt ist oder nicht. In diesem Fall liegt der Unterschied nur in der Einmaligkeit oder Mehrmaligkeit. Ein sehr guter Satz von Tests …, die endlos ausgeführt werden, ist Monitoring. Und richtiges Monitoring sollte so sein.

Und wie genau Sie diesen Zustand erreichen, in dem Sie am Freitagabend deployen und nach Hause gehen, ist eine andere Frage. Vielleicht sind Sie einfach ein mutiger Typ.

Lass uns einen Schritt zurück zu Continuous Integration machen. Wir sind ein wenig in eine andere komplexe Praxis abgedriftet.

Und die zweite Illusion ist, dass man MVP angeblich schnell erstellen muss, weshalb Tests dort überhaupt nicht notwendig seien. Das ist nicht ganz richtig. Es geht darum, dass man, wenn man im MVP eine User Story schreibt, diese entweder unbedacht umsetzt, d. h. man hat gehört, dass es eine User Story gibt, und springt sofort ins Codieren, oder nach TDD arbeitet. Und nach TDD, wie die Praxis zeigt, dauert es nicht länger, d. h. Tests sind ein Nebeneffekt. Die TDD-Praxis besteht nicht darin, Tests zu schreiben. Trotz des Begriffs Test Driven Development geht es dabei in Wirklichkeit gar nicht um Tests. Es handelt sich eher um einen architektonischen Ansatz. Es ist ein Ansatz, um genau das zu schreiben, was nötig ist, und nicht das, was nicht nötig ist. Diese Praxis fokussiert darauf, wie man die nächste Iteration seines Denkens in Bezug auf die Erstellung der Anwendungsarchitektur angeht.

Es ist also nicht so einfach, sich von diesen Illusionen zu befreien. MVP und Tests widersprechen sich nicht. Ganz im Gegenteil, wenn Sie das MVP nach der TDD-Praxis erstellen, werden Sie es besser und schneller umsetzen, als wenn Sie ohne diese Praxis arbeiten und einfach drauflos programmieren.

Das ist ein sehr unauffälliger und komplexer Gedanke. Wenn du hörst, dass du jetzt noch Tests schreiben musst und dabei etwas schneller machst, klingt das absolut unangemessen.

(Dmitry) Viele, wenn sie von MVP sprechen, haben einfach keine Lust, etwas Vernünftiges zu schreiben. Und das sind immer noch verschiedene Dinge. Man sollte MVP nicht in eine schlechte Sache verwandeln, die nicht funktioniert.

Ja, ja, du hast recht.

Und dann kommt plötzlich das MVP in die Produktion.

Für immer.

TDD klingt sehr ungewohnt, wenn man hört, dass man Tests schreibt und dabei scheinbar mehr Arbeit verrichtet. Das klingt sehr seltsam, aber in Wirklichkeit bekommt man es dadurch schneller und schöner hin. Wenn du einen Test schreibst, denkst du bereits viel darüber nach, welchen Code und wie er aufgerufen wird sowie welches Verhalten wir von ihm erwarten. Du sagst nicht einfach, dass du eine Funktion geschrieben hast und sie etwas macht. Du hast zuerst darüber nachgedacht, dass sie unter bestimmten Bedingungen so aufgerufen wird. Du deckst das mit Tests ab und daraus verstehst du, wie deine Schnittstellen innerhalb deines Codes aussehen werden. Das hat einen großen Einfluss auf die Architektur. Dein Code wird automatisch modularer, weil du zuerst versuchst zu verstehen, wie du ihn testen wirst, und erst dann schreibst du ihn.

Ich habe mit TDD Folgendes erlebt: Irgendwann habe ich einen Mentor für Ruby engagiert, als ich noch Ruby-Programmierer war. Und er sagt: „Lass uns TDD ausprobieren“. Ich dachte mir: „Verdammtes A, jetzt muss ich noch mehr zusätzlich schreiben“. Und wir haben uns darauf geeinigt, dass ich zwei Wochen lang allen funktionierenden Code in Python nach TDD schreibe. Nach zwei Wochen habe ich realisiert, dass ich nicht mehr zurückwill. Nach zwei Wochen, in denen ich versucht habe, das überall anzuwenden, verstehst du, wie viel einfacher es geworden ist, sogar nur zu denken. Aber das ist nicht offensichtlich, deshalb empfehle ich jedem, dass, wenn ihr das Gefühl habt, TDD ist kompliziert, langwierig und unnötig, versucht es einfach für zwei Wochen. Mir haben zwei Wochen dafür gereicht.

(Dmitri) Wir können diesen Gedanken aus der Sicht der Infrastruktur-Operationen weiter ausführen. Bevor wir etwas Neues starten, machen wir ein Monitoring und starten dann. In diesem Fall wird unser Monitoring zu einer normalen Testung. Und es gibt eine Entwicklung durch Monitoring. Aber fast alle sagen, dass es lange dauert, ich habe keinen Bock, ich habe einen vorläufigen Entwurf gemacht. Wenn wir richtiges Monitoring gemacht haben, verstehen wir den Zustand des CI-Systems. Und im CI-System gibt es viel Monitoring. Wir verstehen den Zustand des Systems, wir verstehen, was sich darin befindet. Und während der Entwicklung stellen wir bewusst das System so ein, dass es den gewünschten Zustand erreicht.

Diese Praktiken sind schon lange bekannt. Wir haben vor etwa 4 Jahren darüber diskutiert. Aber in den 4 Jahren hat sich praktisch nichts geändert.

Aber in dieser Note schlage ich vor, die offizielle Diskussion zu beenden.

Video (als Medienelement eingefügt, funktioniert aber irgendwie nicht):

https://youtu.be/zZ3qXVN3Oic

Quelle: habr.com

60GB SSD 8Gb DDR4