Facebook
Twitter
Google+
Kommentare
5

Nebenläufigkeit mit PHP oder Das Märchen vom Hasen, der Schlange und einem Wurm

Es war einmal vor langer Zeit als es sich begab, dass der König vom lange untergegangen europäischen Königreich Lycos eine Aufgabe an seine Programmier-Ritter stellte, ein Erfindung zu machen, dass Bürger von Lycos gleichzeitig mehrere Videos hochladen und während der Transcodierung in ein FLV weiterarbeiten können.

Ich möchte kurz darauf eingehen wie wir die Aufgabe damals gelöst haben und wie man sie heute lösen könnte. Dazu muss natürlich gesagt werden, dass „damals“ vor 6 Jahren war, PHP-Frameworks gerade erst entstanden und die Verwendung der damals sehr neuen AJAX-Technologie noch mühsam war. Der IE 5.5 war noch Teil der Liste von Browsern für die entwickelt wurde und Firefox 2.x kam gerade erst aus den Kinderschuhen heraus.

In diesem Umfeld war die gestellte Aufgabe nicht einfach zu lösen. Klar war, dass die transkodierung eines Videos sehr viele Ressourcen verbrauchen würde, die auf den Standard-Frontend-Maschinen nicht zur Verfügung stand. Zudem musste berücksichtigt werden, dass die Anzahl der Transkodier-Maschinen erhöht werden konnte, damit die zu erwarteten „Massen“ der Videonutzer (Das war zum Beginn von youtube.com) bedient werden konnten und sogar die Transkodierung als Service für andere Lycos-Sites anzubieten.

Ob SOA als Begriff schon existierte, weiss ich nicht mehr genau (Das Reference Model vor Service Oriented Architecture 1.0 kam (laut Wiki) im August 2006 heraus), aber wir brauchten genau das. Einen Entkoppelten Service für unsere Applikation. Und den bauten wir dann auch.

Geplant waren insgesamt 3 Wochen für die Realisierung. Es wurden nachher 3 Monate und es wurden leider nicht alle fachlichen Anforderungen erfüllt, denn die Nutzer konnten nur auf der einen Seite „weiterarbeiten“ auf der auch der Upload stattfand. Wenn die Verbindung zum Beispiel durch einen Reload unterbrochen wurde, war das Video weg.

Während des Uploads fand auch die Transkodierung des Videos statt, da damals noch nicht so viel Bandbreite für den Massenmarkt zur Verfügung standen und ein Upload länger dauerte als eine Transkodierung, war dies eine gute Möglichkeit Zeit zu sparen. Während des Uploads und der Transkodierung pullte ein 2ter AJAX-Request permanent den Fertigstellungsstatus. Wenn 100% des Videos transkodiert waren wurde dem User eine Mitteilung (PopUp) gezeigt, dass das Video fertig ist. Dieser Service war sehr anfällig und die Ausnahmebehandlungen der verschiedenen Videoformate wurden in immer längerem Wurm-Code umgesetzt. Am Ende waren es insgesamt 12 Bildschirmseiten voll prozeduralem Perl-Code. Zu dem war noch ein Patchen (und damit warten) eines Apache-Moduls notwendig. Insgesamt also: Alles andere als ein stabiler, skalierbarer Service.

Interessant ist natürlich nun die Frage, wie man mit der heute verfügbaren Technologie diese Anforderungen umsetzen könnte. Im Bereich der JS-Frameworks hat sich jQuery (für mich) als der momentane Favorit erwiesen, den ich heute wählen würde, um einen Video-Upload per AJAX umzusetzen. Den eigentlichen Transkodier-Befehl könnte man sicherlich recyceln nur würde ich heute nicht mehr beim Upload transkodieren, weil das direkte Arbeiten auf einem Stream einfach zu anfällig ist. Dadurch verliert man natürlich Zeit und Kontrolle.

Eine Lösung könnte so aussehen, dass der Client, nach dem der Upload abgeschlossen ist, dem System mitteilt, dass die Transkodierung stattfinden soll. Damit verlagert man die Kontrolle in den Client, der aber mit dem Prozess eigentlich nichts zu tun hat.

Die bessere Lösung ist die Verwendung einer Working-Queue. Diese Working-Queue arbeitet so, dass Clients Nachrichten in die Queue einstellen und so genannte Worker diese Nachrichten „lesen“ und bearbeiten. Die oben beschriebenen Probleme würden so gelöst werden, dass ein Client eine Nachricht in die Working-Queue schreibt, dass ein Video fertig geladen ist. Natürlich würde die Nachricht beinhalten wo sich das geladene Video befindet und welche Transkodierung stattfinden soll.

Ein Worker der gerade „frei“ ist würde anschließend die Nachricht aufnehmen und eine definierte Callback-Funktion ausführen. Diese würde dann das Video transkodieren. Anschließend würde wiederum eine Nachricht in die Working-Queue gegeben, dass das Video fertig ist. Ein weiterer Worker würde daraufhin ein Flag setzen, dass das Video fertig ist. Nachdem der User den Upload beendet hat ist er nicht mehr an das System gebunden und kann andere Dinge machen. Beim nächsten Besuch der Seite oder nach einer gewissen Zeitspanne wird er informiert, dass das oder die Videos, die er beim letzten Besuch geladen hat fertig sind. Auch andere Nachrichten können so an den User „gesendet“ werden.

Es gibt einige mögliche Systeme, die zu diesem Zweck eingesetzt werden können. Eine schöne Übersicht ist hier zu finden: Message-Queue-Evaluation-Notes. Eine einfache Lösung bietet Gearman oder zum Beispiel RabbitMQ.

Dabei ist Gearmen sehr viel einfacher zu nutzen, Rabbit MQ aber deutlich vielfältiger. Die Working-Queues sind nur eine von vielen Einsatzmöglichkeiten von Rabbit-MQ. Die vielfältigen Einsatzmöglichkeiten von RabbitMQ werde ich einem anderen Artikel zeigen.

Über den Autor

Mike Lohmann

Mike Lohmann arbeitet zur Zeit als Software Architekt beim Verlag Gruner+Jahr AG & Co KG. Er arbeitet seit 1998 im IT-Bereich und seit 2000 im Bereich Webentwicklung.
Kommentare

5 Comments

  1. Auch wenn ich mir von dem Artikel mehr versprochen habe (wie kann ich Nebenläufigkeit in PHP umsetzen), so war er doch eine ganz gute Einführung in die Problematik.
    Ergänzend könnte man noch hinzufügen, dass mit dropr (https://github.com/s0enke/dropr/wiki/) eine Message-Queue-Implementierung in PHP existiert.

    Reply
  2. Ich bin mir ganz sicher, dass hier heute Morgen noch ein Kommentar von mir stand…

    Daher nochmal:

    Auch wenn ich der Meinung bin, dass der Artikel für meinen Geschmack nicht tief genug in die Materie Einblick gewährt – ich hätte mir einen Bezug zu dem Märchen gewünscht – finde ich, dass er einen guten Einblick in die Materie darstellt.

    Eine kleine Ergänzung noch: mit dropr gibt es eine Messe-Queue-Implementierung in PHP.

    Reply
  3. @Simon: Mike wird noch einen Artikel verfassen, in dem er schreibt, wie man das ganze heute machen würde. Ich glaube aber, dass es ein wenig in Richtung RabbitMQ und Gearman gehen wird. Aber lassen wir uns überraschen.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen