Anwendungs-Performance-Engineering
Laravel-Performance & Skalierung
Anwendungen, die unter Last halten - gemessen an der Produktion statt an einem Laptop, an der Ursache behoben und durch Budgets in der CI verteidigt, damit die Zahlen bleiben.
Performance-Arbeit hat ein vorhersehbares Ende. Ein Sprint geht in die Optimierung, die Kurven gehen runter, und anderthalb Monate später sitzen sie genau dort, wo sie angefangen haben. Die Korrekturen waren nicht falsch. Es hielt sie nur nichts an ihrem Platz.
Wie ein Projekt abläuft
Zuerst messen, aus der Produktion. Echter Traffic, in Stichproben, nach Endpunkt getrennt. Ein p95 von 2,4 Sekunden auf der Bestellübersicht ist eine handlungsfähige Aussage; „die App fühlt sich langsam an" ist es nicht, und ein Profil von einer Entwicklermaschine gegen eine befüllte Testdatenbank ebenfalls nicht.
Die Ursache finden, nicht das Symptom. Ein langsamer Endpunkt in Laravel ist fast immer eines von fünf Dingen: die Abfragezahl, eine einzelne Abfrage ohne brauchbaren Index, Arbeit die in eine Queue gehört hätte, ein Aufruf bei Dritten im Anfragepfad, oder das Serialisieren von weit mehr Daten als die Antwort braucht. Wir führen jedes davon auf die Zeile zurück, die es erzeugt hat.
Auf der richtigen Ebene beheben. Arbeit in einen Job verlagern, den Index hinzufügen, den der Abfrageplan tatsächlich will, die Relation vorab laden, eine Collection-Pipeline durch ein Aggregat ersetzen, einen Wert cachen dessen Kosten das Invalidierungsproblem wirklich rechtfertigen. Das sind die Änderungen, die halten.
Das Ergebnis verteidigen. Ein Budget in der CI: eine Zusicherung auf die Abfragezahl der Endpunkte, die zählen, und ein fehlschlagender Build für den Pull Request, der sie überschreitet. Das Budget ist das Ergebnis; die Kurve ist ein Nebeneffekt.
Warum die Kurve zurückkommt
Weil eine Kurve ein Resultat ist und niemand für ein Resultat verantwortlich ist. Ein Budget ist eine Zahl in einem Test, von einer Maschine geprüft, bei jedem Pull Request, und es lässt den Build desjenigen scheitern, der sie überschritten hat, solange er sich noch erinnert, was er geändert hat.
Deshalb brauchen die meisten Kunden uns dafür kein zweites Mal. Ohne Budget zu optimieren heißt, gegen das nächste Quartal zu borgen: dieselbe Relation verliert still ihr Vorab-Laden, derselbe Report bekommt eine weitere Spalte, die sich als Accessor mit einer Abfrage dahinter entpuppt, und der Rückfall kommt in vernünftigen Commits, einer nach dem anderen, von Leuten die es nicht wissen konnten.
Wohin die Zeit tatsächlich geht
Sortiert danach, wie oft es die Antwort ist:
Die Datenbank. Meist die Abfragezahl statt einer einzelnen Abfrage – weshalb es ein eigenes Projekt ist, wenn es das ganze Problem ist statt eines Teils davon.
Arbeit, die nicht in die Anfrage gehört. Ein gerendertes PDF, ein skaliertes Bild, ein zugestellter Webhook, ein erzeugter Report. Jedes davon gehört in eine Queue, und sie zu verlagern ist meist die größte verfügbare Verbesserung.
Ein Dritter im kritischen Pfad. Eine Adressprüfung, ein Steuerdienst, der Statusaufruf eines Zahlungsdienstleisters. Deren Latenz ist Ihre Latenz, deren Ausfall ist Ihr Ausfall, und beides ist in Ihrem eigenen Profiling nicht sichtbar, bis Sie danach suchen.
Serialisierung. Ein Endpunkt, der zweihundert Felder zurückgibt, weil die Resource als „alles am Modell" geschrieben wurde und Relationen hydriert, um eine Namensliste zu erzeugen.
Cache als Pflaster. Caching ist nicht umsonst – es kauft Geschwindigkeit mit Veralterung, und eine Anwendung mit einem Dutzend unzusammenhängender Cache-Schlüssel und ohne Invalidierungsstrategie hat ein Performance-Problem gegen ein Korrektheitsproblem getauscht.
Skalieren, sobald sie effizient ist
Erst dann ist Infrastruktur die Antwort, und die Reihenfolge zählt: Eine ineffiziente Anwendung horizontal zu skalieren ist eine ineffiziente Anwendung, für die Sie mehrfach zahlen.
Wo es gerechtfertigt ist, besteht die Arbeit aus Read Replicas mit explizit statt global entschiedenem Routing, Sitzungs- und Cache-Speichern die nicht die Hauptdatenbank sind, Queue-Workern die getrennt von der Web-Kapazität skaliert werden weil sie anders scheitern, und einem Deployment das laufende Arbeit nicht fallen lässt. Octane dort, wo die Messung sagt, dass der Framework-Boot tatsächlich ein nennenswerter Anteil der Anfrage ist – was seltener ist, als sein Ruf nahelegt.
Was Sie bekommen
Ein priorisiertes Befunddokument, in dem jedes Problem auf seine Ursache zurückgeführt und nach Aufwand bemessen ist, die umgesetzten Korrekturen als prüfbare Pull Requests, die Konfiguration des CI-Budgets, und einen Vorher-Nachher-Vergleich gegen echten Traffic, sobald die Änderung lange genug live war, um etwas zu bedeuten.
Wo sich die Decke als die Architektur selbst herausstellt – was vorkommt – sagen die Befunde das und stellen eine Zahl für die Alternative daneben. Das ist ein Gespräch für Woche eins und nicht für die Abschlusszusammenfassung.
