PHP wurde über viele Jahre hinweg als „langsam“ abgestempelt. Der Hauptgrund dafür war das Arbeitsmodell, das bei jeder Anfrage von Null begann. Jede eingehende HTTP-Anfrage startete PHP neu, kompilierte das Skript, lud Ressourcen und nach Abschluss der Verarbeitung wurde alles wieder gelöscht. Dieser Zyklus stellte insbesondere bei stark frequentierten Anwendungen eine erhebliche Belastung dar. Genau hier kommen Werkzeuge wie Swoole und RoadRunner ins Spiel. In diesem Artikel werde ich beide Technologien unter die Lupe nehmen, erklären, wie sie funktionieren, und beschreiben, was sie in der realen Welt versprechen.
Einschränkungen des traditionellen PHP
Ein typischer Webserver mit PHP-FPM erzeugt für jede Anfrage einen eigenen Prozess. Dieser Prozess liest Konfigurationsdateien, lädt alle Erweiterungen, führt die Abhängigkeiten der Anwendung aus (z.B. Composer Autoload), verarbeitet die Anfrage und beendet sich. Stellen Sie sich 10.000 gleichzeitige Verbindungen vor: Für jede einen separaten PHP-Prozess zu öffnen, ist sowohl in Bezug auf CPU als auch RAM eine enorme Verschwendung. Selbst wenn die Neustartkosten pro Verbindung nur 30–50 ms betragen, summieren sich diese Zeiten in nicht zu unterschätzender Weise. Denken Sie an eine API-Anwendung; wenn Sie aufgrund dieser Zeiten nicht über 200 Requests pro Sekunde hinauskommen, liegt das Problem nicht in Ihrem Code, sondern im Arbeitsmodell.
Swoole: Ein asynchroner Ansatz für PHP
Swoole ist ein als C-Erweiterung für PHP entwickeltes Programmierframework. Im Gegensatz zu traditionellem PHP macht es Ihre Anwendung im Arbeitsspeicher persistent. Beim ersten Start wird das gesamte Skript geladen, Verbindungen werden über dieselben Prozesse abgewickelt, und es gibt kein zustandsloses Modell. Eine der wichtigsten Eigenschaften von Swoole ist die Unterstützung von asynchronem I/O und Coroutinen. So ist es beispielsweise sehr einfach, einen HTTP-Server einzurichten: Mit wenigen Codezeilen können Sie Tausende gleichzeitige Verbindungen verwalten. Darüber hinaus lassen sich WebSocket-, TCP-/UDP-Server in derselben Codebasis betreiben.
Coroutinen sind der entscheidende Punkt. Normalerweise ist ein Funktionsaufruf in PHP blockierend. Mit Swoole können Sie Coroutinen verwenden, um während des Wartens auf eine Datenbankabfrage eine andere Anfrage zu bearbeiten. Auf diese Weise können Sie in demselben Prozess Tausende von Vorgängen mit sehr geringem Ressourcenverbrauch ausführen. Stellen Sie sich die Versandabfrage-API einer E-Commerce-Website vor; ein HTTP-Aufruf an einen externen Dienst dauert 200 ms. Bei traditionellem PHP würde der Prozessor in dieser Zeit untätig warten. Bei Swoole hingegen können Sie in diesen 200 ms andere Anfragen bearbeiten und so die Effizienz vervielfachen.
RoadRunner: PHP mit der Leistung von Go kombinieren
RoadRunner verfolgt einen etwas anderen Ansatz. Es ist ein in Go geschriebener schneller Anwendungsserver, der PHP-Worker verwaltet und eingehende Anfragen an diese Worker verteilt. Im Grunde führen Sie Ihren PHP-Code also über einen Go-Server aus. Sobald die PHP-Worker gestartet sind, bleiben sie im Speicher; nach einer Anfrage wartet der Worker auf die nächste. Dies ist keine asynchrone Struktur wie bei Swoole, aber durch die Beseitigung der Startkosten bietet es einen erheblichen Leistungsgewinn.
Das wichtigste Merkmal, das RoadRunner von Swoole unterscheidet, ist, dass keine Änderungen auf PHP-Seite erforderlich sind. Sie können ein bestehendes Laravel- oder Symfony-Projekt nahezu ohne Codeänderungen mit RoadRunner betreiben. Swoole hingegen erfordert speziell geschriebenen, coroutinenkompatiblen Code (obwohl einige Frameworks kompatibel sind). Darüber hinaus unterstützt RoadRunner nativ moderne Protokolle wie gRPC, HTTP/2 und WebSocket.
Vergleich und Entscheidungshilfe
Welches Werkzeug Sie wählen, hängt von der Struktur Ihres Projekts ab. Wenn Sie ein neues Projekt von Grund auf entwickeln und die volle Kontrolle wünschen, ist Swoole flexibler und leistungsfähiger. Allerdings ist die Lernkurve etwas steiler. Beispielsweise kann ein mit Swoole geschriebener HTTP-Server auf derselben Hardware 10- bis 20-mal mehr Anfragen verarbeiten als PHP-FPM. In meinem eigenen Test erreichte Swoole bei einer einfachen „Hello World“-Anwendung 50.000 Requests pro Sekunde, während PHP-FPM bei 2.000 hängen blieb.
RoadRunner ist ideal für bestehende Projekte. Vor allem, wenn Sie schnell eine Leistungssteigerung erzielen möchten, dauert die Installation und Konfiguration von RoadRunner nur Minuten. In Verbindung mit Laravel habe ich eine Reduzierung der Antwortzeiten um bis zu 50 % beobachtet. Dadurch, dass RoadRunner in Go geschrieben ist, erledigt es Aufgaben wie Lastverteilung und Prozessverwaltung sehr effizient.
Beispiele aus der Praxis
In einer Finanzanwendung haben wir mit Swoole 10.000 gleichzeitige WebSocket-Verbindungen mit 100 MB Arbeitsspeicher verwaltet. Im Vergleich zu Node.js war der Speicherverbrauch bei gleicher Auslastung fast halb so hoch. In einem anderen Projekt, einer E-Commerce-Website, die mit RoadRunner betrieben wurde, sanken die Seitenladezeiten von 300 ms auf 80 ms. Diese Verbesserungen wirken sich direkt auf die Benutzererfahrung aus.
Zusammenfassend lässt sich sagen, dass der Mythos, PHP sei langsam, nicht mehr haltbar ist. Mit Werkzeugen wie Swoole und RoadRunner können Sie mit PHP Zehntausende von Anfragen pro Sekunde verarbeiten. Entscheidend ist die Wahl des richtigen Werkzeugs und die entsprechende Konfiguration entsprechend den Anforderungen Ihres Projekts. Scheuen Sie sich nicht, es auszuprobieren; testen Sie Swoole oder RoadRunner mit einer kleinen Anwendung und sehen Sie den Unterschied selbst.