Plattformmigration
Migration von Legacy-PHP zu Laravel
CodeIgniter, Zend, Symfony 2 oder ganz ohne Framework - schrittweise nach Laravel überführt, hinter einem Router, der jede Route an das System schickt, dem sie gerade gehört.
Eine Anwendung, 2014 in CodeIgniter geschrieben, oder in Zend, oder Symfony 2, oder ganz ohne Framework - läuft noch, verdient noch Geld, und ist jetzt auf eine bestimmte Art teuer. Niemand fasst sie an, die Leute, die sie geschrieben haben, sind weg, und die PHP-Version, die sie braucht, hat keinen Support mehr.
Der Vorschlag, der dann meist kommt, ist eine Neuentwicklung. Sie hat die falsche Form für dieses Problem, und daran scheitern diese Projekte.
Warum die Neuentwicklung das Risiko ist
Neuentwicklung heißt, ein zweites System neben dem ersten zu bauen und umzuschalten, wenn es fertig ist. Daraus folgen drei Dinge, und alle drei sind vorhersehbar.
Das Geschäft bekommt währenddessen keine Änderungen mehr, denn jede Stunde am alten System ist weggeworfen. Die Ziellinie verschiebt sich, weil die Anforderungen nie aufgeschrieben wurden und im Code neu entdeckt werden, sobald man auf sie stößt. Und die Umstellung ist ein einzelner Tag, an dem jede Regel, an die sich niemand erinnerte, gleichzeitig in Produktion getestet wird.
Die Regeln sind das Problem. Ein System, das ein Jahrzehnt gelaufen ist, enthält Entscheidungen, die es sonst nirgends gibt: warum diese Kundengruppe befreit ist, warum der Export um 03:40 läuft, warum ein Preisfeld ignoriert wird. Eine Neuentwicklung findet sie eine Beschwerde nach der anderen.
Stattdessen Route für Route
Setzen Sie einen Router vor beide Systeme. Er schickt jede Anfrage an die Anwendung, der dieser Pfad gerade gehört - Laravel für das Umgezogene, die Altanwendung für den Rest.
location /account/ { proxy_pass http://laravel; }
location / { proxy_pass http://legacy; }Jetzt ist eine Migration eine Folge kleiner Deployments statt eines großen. Jede umgezogene Route ist in derselben Woche live, jede lässt sich mit einer Zeile zurücknehmen, und das Geschäft liefert die ganze Zeit weiter aus.
In der Praxis entscheidet die Reihenfolge:
- Erst die Bestandsaufnahme. Jede Route, jede geplante Aufgabe, jede Anbindung, und was jede davon berührt. Aus dem Code und der Datenbank, nicht aus der Erinnerung.
- Sessions und Authentifizierung gemeinsam. Beide Systeme müssen sich vom ersten Tag an einig sein, wer angemeldet ist, sonst wird ein Nutzer beim Überqueren der Grenze abgemeldet. Meist ein gemeinsamer Session-Speicher und ein System, dem der Login gehört.
- Die Datenbank bleibt. Beide Anwendungen lesen dieselben Tabellen. Das Schema wird später für sich verbessert, damit eine Regression einer Änderung zuzuordnen ist und nicht zweien.
- Blattrouten zuerst. Etwas Abgeschlossenes mit wenig Verkehr, um Routing, Deployment und Rücknahme zu beweisen, bevor etwas Wichtiges davon abhängt.
- Dann nach Wert. Die Routen, die am häufigsten geändert werden, denn dort wird der Preis des alten Systems tatsächlich bezahlt.
- Geplante Arbeit und Anbindungen zuletzt. Ihnen sieht niemand zu, und sie haben den meisten verborgenen Zustand.
Die wirklich schwierigen Teile
Sessions. Zwei Frameworks, zwei Session-Formate. Entweder liest ein System das Format des anderen, oder beide ziehen auf einen gemeinsamen Speicher mit einer gemeinsamen Serialisierung um. Das wird vor der ersten Route entschieden, nicht von einem ausgeloggten Kunden entdeckt.
Alte Passwort-Hashes. Sie können nicht umwandeln, was Sie nicht lesen können. Laravel prüft beim Login gegen den alten Algorithmus und hasht bei Erfolg neu, sodass sich die Datenbank beim Anmelden selbst umwandelt statt über eine Zurücksetzungs-Mail an alle gleichzeitig.
Tabellen, die das ORM des alten Systems geformt hat. Zusammengesetzte
Schlüssel, keine Zeitstempel, ein anders benannter Primärschlüssel, ein
Boolescher Wert als 'Y'. Eloquent-Modelle werden auf diese Tabellen
konfiguriert, statt die Tabellen für Eloquent zu ändern - das kommt später,
wenn überhaupt.
Zwei Codebasen schreiben dieselben Zeilen. Die Regel lautet, dass jedem Schreibpfad zu jedem Zeitpunkt genau ein System gehört. Wenn beide dieselbe Tabelle schreiben, kommt daher die Datenkorruption in diesen Projekten.
Was wir nicht tun
Wir ziehen nicht alles um. Manche dieser Projekte enden mit einer kleinen Altanwendung, die noch eine Handvoll Routen bedient, die niemand ändern muss, und das ist ein legitimer Abschluss - das Ziel war, die Kosten zu beenden, nicht eine Zahl zu erreichen.
Wir verbessern kein Verhalten beim Umzug. Eine Route wird so umgezogen, dass sie genau das tut, was sie tat, Fehler eingeschlossen, und danach in einem eigenen Commit verbessert. Verhalten und Ort gleichzeitig zu ändern heißt, dass eine Regression zwei mögliche Ursachen hat und keine günstige Art, sie zu unterscheiden.
Wie ein Projekt abläuft
Das Erste, was wir brauchen, ist die Routing-Tabelle dessen, was jetzt da ist, und eine ehrliche Auskunft darüber, welche Teile niemand mehr versteht.
Daraus entsteht ein Routenverzeichnis und ein phasenweiser Leistungsumfang mit einem Preis je Phase. Er sagt, welche Routen zuerst umziehen, was während des Umzugs daneben weiterläuft und welche Teile wir Ihnen empfehlen gar nicht zu migrieren. Dieses Dokument ist das, woran der Vertrag hängt.
Dann die Phasen. Beide Anwendungen laufen zusammen, bis die letzte Route umgezogen ist, und jede Phase endet mit etwas in Produktion.
Was Sie bekommen
Eine Routing-Schicht mit einer expliziten Karte, welchem System was gehört, die Bestandsaufnahme, aus der diese Karte entstand, umgezogene Routen mit Tests, die beim Umzug entstanden sind, und eine Reihenfolge für den Rest mit der Begründung dazu.
Wenn die Anwendung bereits Laravel ist und nur mehrere Versionen zurückliegt, ist das hier nicht die Arbeit, die Sie brauchen - Upgrades und Rettung ist es, und das ist ein kleinerer Auftrag.
