Der Engpass ist gemessen.
Profiling, Lastdaten oder Betriebsmetriken zeigen, welcher abgegrenzte Pfad die Anwendung begrenzt.
Go neben PHP
Der übliche Vorschlag heißt Rewrite: alles in Go neu, in zwölf Monaten, mit demselben Team, das nebenbei den Betrieb hält. Wie das ausgeht, wissen Sie. Es geht auch anders. Der eine Pfad, der unter Last einbricht, wird herausgelöst und als Go-Dienst neben Ihr PHP gestellt, angebunden über gRPC oder HTTP, mit derselben Datenbank oder einer klaren Grenze. Der Rest bleibt, wo er ist. Und davor wird gemessen: Wenn der Engpass in der Datenbank sitzt, ändert eine andere Sprache daran nichts, und dann sage ich Ihnen das, bevor Sie etwas beauftragen.
Eine Woche, ein Ergebnis, zum Festpreis. Die Produktivstellung wird danach nach Umfang angeboten, nie als offene Rechnung.
Remote aus Deutschland. Direkt mit mir, ohne Agentur dazwischen.
Die Ausgangslage
Fast jedes gewachsene PHP-System hat eine Handvoll Stellen, die anders sind als der Rest: der Endpunkt, den die App bei jedem Start aufruft. Der Import, der nachts vier Stunden läuft. Die Suche, die zur Spitzenlast alles andere mitzieht. Das Ausführungsmodell von PHP ist für den größten Teil einer Anwendung völlig ausreichend, aber es passt schlecht zu langlebigen Verbindungen, zu Arbeit, die parallel laufen soll, und zu Aufrufen, die im einstelligen Millisekundenbereich beantwortet werden müssen.
Wenn das auffällt, liegt oft schon ein Vorschlag auf dem Tisch: neu bauen, diesmal in Go. Das ist eine Entscheidung über zwölf Monate, in denen niemand etwas anderes liefert und das alte System trotzdem gepflegt werden muss. Der schmalere Weg heißt Strangler Fig und ist keine neue Idee: Man löst genau den einen Pfad heraus, stellt ihn als eigenen Dienst daneben, lenkt den Verkehr schrittweise um und lässt alles andere unangetastet. Kein Stichtag, kein großer Knall, und an jeder Stelle ein Rückweg.
Und dann kommt die Hälfte, die in keinem Angebot steht: Sehr oft lohnt sich das nicht. Der häufigste Grund für einen langsamen Pfad ist nicht die Sprache, sondern eine Abfrage ohne passenden Index, ein N+1 im ORM, eine Datenbank, die an ihrer Grenze läuft, oder ein fremder Dienst, auf den gewartet wird. In allen vier Fällen wartet ein Go-Dienst genauso lange wie das PHP davor, nur mit mehr beweglichen Teilen. Deshalb steht hier die Messung vor dem Bau. Zeigt sie in die Datenbank, sage ich das und wir hören dort auf.
Kommt Ihnen etwas davon bekannt vor?Für wen das passt
Das Angebot richtet sich an CTOs und Backend-Leads mit einer produktiven PHP-Anwendung. Ein klarer Pfad stößt bei Last, Parallelität oder Latenz an Grenzen, während der übrige Monolith zuverlässig weiterarbeitet.
Profiling, Lastdaten oder Betriebsmetriken zeigen, welcher abgegrenzte Pfad die Anwendung begrenzt.
Der bestehende Monolith wird nicht entwertet. Go übernimmt nur den Teil, für den sich die zusätzliche Sprache technisch rechnet.
Deployment, Monitoring, Schnittstelle und Wissenstransfer gehören deshalb genauso zum Auftrag wie der Go-Code.
Was ich mache
Ein Lasttest gegen den verdächtigen Pfad und eine Ablaufverfolgung, die zeigt, wo die Zeit hingeht: Datenbank, Serialisierung, Netz und Interpreter getrennt ausgewiesen. Das Ergebnis ist eine Aufteilung in Millisekunden und ein Satz dazu, ob ein eigener Dienst hier überhaupt etwas ändert. Fällt der Satz negativ aus, steht er trotzdem im Bericht, und dort endet das Paket.
Herausgelöst wird das kleinste Stück, das für sich stehen kann, mit klar benanntem Ein- und Ausgang. Nicht ein Modul, nicht eine Domäne, nicht „der Bestellprozess", sondern der eine Aufruf, der die Last trägt. Je enger der Schnitt, desto kürzer der Weg zurück.
Ein Dienst, kein Ökosystem: ein Binary, wenige Abhängigkeiten, Nebenläufigkeit dort, wo sie etwas bringt, und ein Speicherbedarf, den man vorhersagen kann. Dazu Tests, die den bisherigen Pfad nachbilden, damit die Ablösung überprüfbar ist und nicht nur plausibel. Er entsteht in einem eigenen Zweig und wird dort gegen echte Daten gemessen.
gRPC mit Protocol Buffers, wenn die Aufrufe häufig sind und ein Vertrag helfen soll. Das setzt allerdings einen dauerhaften PHP-Prozess voraus, etwa RoadRunner oder FrankenPHP, oder Aufrufe, die den Verbindungsaufbau je Anfrage vertragen: Unter klassischem PHP-FPM ist der Prozess kurzlebig, der gRPC-Kanal überlebt die Anfrage nicht, und genau die Wiederverwendung der HTTP/2-Verbindung ist der Vorteil von gRPC. Dort ist schlichtes REST mit Keep-Alive der ehrlichere Weg, ebenso wenn Ihr Team damit besser zurechtkommt. Dazu Zeitüberschreitungen, Wiederholungen und ein Ersatzweg auf den alten Pfad, damit ein ausgefallener Dienst kein ausgefallenes System ist – das gehört zu dem Weg zur Produktivstellung, der in dieser Woche schriftlich entsteht.
Entweder derselbe Datenbestand mit klar geregeltem Zugriff, oder eine eigene Grenze mit einem definierten Weg der Daten. Beides ist in Ordnung, das Dazwischen nicht: Zwei Systeme, die dieselben Tabellen nach eigenem Gutdünken schreiben, sind der Teil, der später weh tut.
Der Verkehr wird über ein Feature Flag umgelenkt, erst ein Bruchteil, dann mehr, und der Weg zurück ist eine Einstellung und keine Auslieferung. Der Dienst läuft dort, wo Sie ohnehin betreiben, beschrieben als Infrastruktur in Code, mit denselben Metriken wie das PHP daneben. Dieser Schritt steht am Ende der Woche schriftlich da, mit Aufwandsschätzung, und wird danach als eigenes Angebot ausgeführt.
Sie haben einen Pfad, der unter Last einbricht?
Schicken Sie mir den Pfad und die Zahlen, die Sie haben. Sie bekommen eine Einschätzung, ob ein eigener Dienst hier etwas ändert, bevor Sie etwas beauftragen.
Ablauf
Vier Schritte in einer Woche. Nach dem zweiten wissen Sie, ob sich der dritte lohnt, und diese Antwort darf Nein lauten.
Welcher Pfad, welche Last, welche Zahlen liegen vor. Oft steht danach schon eine Vermutung im Raum, die nichts mit der Sprache zu tun hat. Wenn ich sie habe, sage ich sie Ihnen sofort und nicht erst am Ende der Woche.
Lasttest und Ablaufverfolgung gegen den Pfad, in einer Testumgebung mit echten Datenmengen oder gegen ein Lastprofil aus Ihrer Produktion. Danach steht in Millisekunden, wo die Zeit verbraucht wird, getrennt nach Datenbank, Serialisierung, Netz und Interpreter. Zeigt das Ergebnis in die Datenbank oder in eine einzelne Abfrage, endet es hier, und Sie behalten den Befund.
Der Dienst, die Schnittstelle und die Grenze zu den Daten, lauffähig in einem eigenen Zweig und gegen echte Daten gemessen. Vorher und nachher am selben Vorgang. In Ihrer Produktivumgebung wird dabei nichts angefasst, und genau deshalb trägt der Festpreis.
Anbindung, Umschaltung über ein Feature Flag, Rückweg und Betrieb, schriftlich und mit Aufwandsschätzung. Damit endet das Paket. Ob Sie diesen Weg mit Ihrem Team gehen oder mit mir, entscheiden Sie danach; von mir bekommen Sie dafür ein eigenes Angebot zum Festpreis, bevor es beginnt.
Die andere Seite
Die Summe steht unten nicht, weil ich sie nicht kenne. Die Posten kenne ich. Ein System, das unter Last einbricht, kostet nicht einmal, sondern jeden Monat weiter. Rechnen Sie selbst nach, dann gehört Ihnen die Zahl.
Rechnen Sie den ersten Posten dieser Liste auf ein Jahr hoch. Kommt dabei mehr heraus, als die Woche unten kostet, ist die Frage nach der Messung schon beantwortet. Sie ersetzt keine dieser Zahlen, aber sie macht die erste davon belegbar, und im Zweifel erspart sie Ihnen den letzten Posten dieser Liste.
Einstieg
Festpreis, und er trägt, weil das Ergebnis eine Messung und ein Zweig in Ihrem Repository ist. In Ihrer Produktivumgebung wird dabei nichts angefasst. Die Produktivstellung wird danach angeboten, ebenfalls zum Festpreis, bevor sie beginnt.
Kein Prototyp und kein Rewrite, sondern eine Woche mit einem Ergebnis: Sie wissen in Millisekunden, wo die Zeit im heißen Pfad verbraucht wird, ob ein Go-Dienst daran überhaupt etwas ändert, und falls ja, liegt der herausgelöste Pfad lauffähig in einem eigenen Zweig, gegen echte Daten gemessen.
Was Sie bekommen
Was Sie nicht bekommen
Das Ergebnis
Nach der Messung steht in Millisekunden, wo die Zeit im heißen Pfad verbraucht wird, getrennt nach Datenbank, Serialisierung, Netz und Interpreter. Damit ist die Frage nach der Sprache beantwortet und nicht vertagt. Lautet die Antwort Ja, liegt der herausgelöste Pfad daneben und der Unterschied steht als Zahl in Ihrem Vorher-Nachher-Test, nicht als Prozentversprechen auf dieser Seite.
Ihr PHP wird nicht abgelöst, nicht umgeschrieben und nicht eingefroren. Ihr Team arbeitet weiter dort, wo es sich auskennt, und muss nicht nebenbei eine zweite Sprache lernen, um eine Fehlerkorrektur auszuliefern.
Der Rückweg ist Teil des Plans, bevor der erste Verkehr umgelenkt wird: Solange das Feature Flag steht und der alte Pfad läuft, ist die Rücknahme eine Einstellung. Das ist der eigentliche Unterschied zum Rewrite. Dort ist der Rückweg nach dem dritten Monat weg, und niemand merkt den Zeitpunkt.
Der Schnitt, die Messstrecke und die Anbindung an PHP sind einmal durchdacht. Der nächste Pfad ist danach eine Entscheidung über den Schnitt und kein neues Vorhaben.
Eingesetzte Technologien
Aus der Praxis
Eine Payment-API für Millionen von Nutzern, die nicht mehr skalierte. Das bestehende Backend wurde zuerst stabilisiert, die neuen Go-Dienste liefen parallel und wurden über gRPC angebunden. Der Verkehr wurde schrittweise umgelenkt, nicht zu einem Stichtag umgeschaltet, ohne Unterbrechung des laufenden Zahlungsbetriebs.
Case Study lesenEbenfalls aus echten Projekten
Wie neue Go-Services in bestehende PHP-Systeme kommen, ohne dass alles umgebaut wird: Strangler Fig in der Praxis statt Big-Bang-Rewrite. Der Erfahrungsbericht hinter dieser Leistung.
Artikel lesen
Mit wem Sie es zu tun haben
Ich bin Tim Rutte. Über 20 Jahre Softwareentwicklung, viele davon in gewachsenen PHP-Systemen, in die ich Go-Dienste gestellt habe, ohne den Betrieb anzuhalten. Sie sprechen mit der Person, die Ihren Code anfasst, vom ersten Gespräch bis zur Übergabe.
Häufige Fragen
Nein, und das ist der Punkt. Ihr PHP bleibt das System, in dem der Alltag stattfindet. Daneben steht ein Dienst, der genau eine Sache tut, und zwar die, für die das Ausführungsmodell von PHP schlecht passt. Wenn dieser Dienst morgen wieder verschwindet, läuft der alte Pfad weiter, solange das Feature Flag steht.
Meistens nicht, und das ist der häufigste Fall. Wenn die Zeit in einer Abfrage ohne passenden Index verbraucht wird, in einem N+1 im ORM, in einer Datenbank an ihrer Grenze oder in der Wartezeit auf einen fremden Dienst, dann wartet ein Go-Dienst genauso lange wie das PHP davor, nur mit mehr beweglichen Teilen. Ohne Messung ist die Sprachfrage ein Münzwurf. Deshalb steht sie hier hinten und die Messung vorn.
Wenn die Zeit im eigenen Code verbraucht wird und nicht im Warten: viele gleichzeitige, langlebige Verbindungen; Arbeit, die parallel laufen könnte, es im Anfrage-pro-Prozess-Modell aber nicht tut; Serialisierung oder Rechnerei in großen Mengen; ein Aufruf, der im einstelligen Millisekundenbereich beantwortet werden muss. Das sieht man in der Ablaufverfolgung, nicht in der Diskussion.
Weil beides zusammengehört, und der PHP-Weg meistens der billigere ist. Ein richtig eingestellter OPcache, Preloading und vor allem aufgeräumte Abfragen holen bei den meisten Pfaden mehr heraus als ein zweiter Dienst. Der JIT gehört ausdrücklich nicht in diese Aufzählung: Er hilft dort, wo tatsächlich gerechnet wird, und das ist selten der Engpass, weil typische Webanwendungen an Ein- und Ausgabe hängen und nicht an der CPU. Dazu kommt, dass sich das Ausführungsmodell selbst ändern lässt, ohne die Sprache zu wechseln: RoadRunner, FrankenPHP und Swoole halten den PHP-Prozess am Leben und gehen damit genau die drei Schwächen an, die oben stehen, nämlich langlebige Verbindungen, Nebenläufigkeit und Aufrufe im einstelligen Millisekundenbereich. Wer noch auf PHP 7 oder älter steht, für den ist ohnehin das Upgrade der erste Hebel, und dafür gibt es hier eine eigene Seite. Go lohnt sich erst dort, wo auch das nicht reicht. Fällt Ihr Fall in eine der Gruppen davor, sage ich das und Sie sparen sich diese Seite.
Das entscheidet Ihr Team mit, und Ihre Laufzeit entscheidet mit. gRPC mit Protocol Buffers ist die bessere Wahl, wenn die Aufrufe häufig sind, ein verbindlicher Vertrag zwischen beiden Seiten helfen soll und auf PHP-Seite ein dauerhafter Prozess läuft, etwa RoadRunner oder FrankenPHP. Unter klassischem PHP-FPM ist der Prozess kurzlebig, der Kanal überlebt die Anfrage nicht, und damit fällt der eigentliche Vorteil von gRPC weg, nämlich die wiederverwendete HTTP/2-Verbindung. Dort und überall, wo Ihre Leute mit REST vertrauter sind, ist schlichtes REST mit Keep-Alive die ehrlichere Wahl. Ein Werkzeug, das im Betrieb niemand versteht, ist kein Fortschritt.
Entweder das, mit klar geregeltem Zugriff, oder eine eigene Grenze mit einem definierten Weg der Daten. Beides funktioniert. Was nicht funktioniert, ist das Dazwischen: zwei Systeme, die dieselben Tabellen nach eigenem Gutdünken schreiben. Welcher der beiden Wege es wird, gehört in den Schnitt und steht fest, bevor gebaut wird.
Das entscheidet der Zuschnitt Ihres Problems und nicht das Alter des Codes. Hier geht es um genau einen Pfad, der unter Last einbricht, während der Rest seinen Dienst tut. Ist dagegen der Bestand selbst das Problem, weil ihn niemand mehr anfassen will, weil es keine Tests gibt und jede Änderung an drei Stellen weh tut, dann ist die Legacy-Modernisierung der passendere Einstieg, und dann sage ich das. Sie hat hier eine eigene Seite unter den Leistungen.
Beide Einstiege kosten 1.900 Euro fest, dauern eine Woche, liefern einen Zweig und belegen mit derselben Case Study. Die Frage ist nur, was bei Ihnen bricht. Geht es um das Mandantenmodell, die Abrechnung oder die Nutzungsmessung, also um den Zuschnitt der Plattform selbst, dann ist die Seite zu SaaS-Plattformen die richtige. Bricht dagegen nicht das Mandantenmodell, sondern ein einzelner Pfad, während der Rest der Plattform trägt, sind Sie hier richtig.
Diese Frage stellt sich vor der Produktivstellung und nicht danach, und das ist der Vorteil des kleinen Zuschnitts: Nach der Woche liegt der Dienst in einem Zweig, der Weg in den Betrieb liegt schriftlich daneben, und erst dann entscheiden Sie. Deshalb bleibt es auch ein Dienst und kein Ökosystem: ein Binary, wenige Abhängigkeiten, dieselben Metriken und dieselbe Auslieferung wie beim Rest. Sagt Ihr Team, es will das nicht betreiben, haben Sie einen Zweig verworfen und keinen zwölften Monat eines Rewrites.
Die Messung mit dem herausgelösten Pfad kostet 1.900 Euro netto, das Ergebnis liegt nach einer Woche vor. Das ist ein Festpreis und kein Startpreis, und der Grund steht im Zuschnitt: Was in dieser Woche entsteht, ist eine Messung und ein Zweig in Ihrem Repository. In Ihrer Produktivumgebung wird nichts angefasst, also hängt der Aufwand auch nicht an fremden Freigaben, Umgebungen und Terminen. Nicht enthalten ist die Produktivstellung, also Anbindung, Umschaltung des Verkehrs und Betrieb. Die wird nach dem Ergebnis angeboten, ebenfalls zum Festpreis, bevor sie beginnt, denn erst dann weiß man, was sie umfasst. Zeigt die Messung, dass ein Go-Dienst nicht das Mittel ist, endet es dort. Bezahlt haben Sie dann eine Woche und eine Antwort, die Ihnen ein Vorhaben von zwölf Monaten erspart, und das ist der billigste Ausgang von allen.
Begriffe, die hier vorkommen
Zum GlossarWeitere Leistungen
Backends für SaaS und Plattformen, die unter echter Last halten: in Go und PHP 8, event-getrieben, mit Mandantentrennung und Wiederanlauf im Entwurf.
Mehr erfahrenVon einer Pipeline, die niemand anfassen will, zu Deployments am Dienstagvormittag: ein Artefakt durch alle Stufen, Zugänge ohne Langzeitschlüssel, geprobter Rückweg.
Mehr erfahrenSaaS-Plattformen, die beim zehnten Kunden noch tragen: entschiedene Mandantentrennung, Abrechnung mit nachvollziehbarer Nutzungsmessung und eine Bruchliste für das zehnfache Volumen.
Mehr erfahren