Als Webentwickler erliegt man oft der Versuchung, dass alle Operationen innerhalb eines Requests abgearbeitet werden, auch wenn diese gar nicht für die Ausgabeseite des Benutzers notwendig sind und durchaus zu einem späteren Zeitpunkt ausgeführt werden könnten. Das bedeutet nicht nur, dass der Webserver unnötigerweise belastet wird, sondern auch, dass der Benutzer lange auf seine Antwort warten muss. In vielen Fällen würde es genügen, die Aufgaben zu einem späteren Zeitpunkt auszuführen. Gerade im Enterprise-Umfeld sind solche Aufgaben an der Tagesordnung. Buchungen von Ressourcen oder Abarbeitung von Bestellungen sind Beispiele, bei denen es meist ausreicht, die Informationen zu sammeln und zeitversetzt zu verarbeiten. Oftmals kümmern sich um die Abarbeitung weitere Systeme, die auf anderen Servern laufen.
Über Message Queues werden solche Aufgaben sowohl zeitlich als auch räumlich von einander gekoppelt. Dabei handelt es sich um Softwarelösungen, die eine Warteschlange zur Verfügung stellen. Meist arbeiten diese nach dem "Publish and Subscribe"-Ansatz. Der Client (Publisher) schreibt Werte (Nachrichten) in die Queue, auf der Serverseite werden diese durch einen Subscriber aus der Warteschlange genommen und verarbeitet. Das Auslesen erfolgt nach dem FiFo-Prinzp (First-in-First-out), die ältesten Nachrichten werden also zuerst ausgelesen. Bei der Auswahl einer Message-Queue-Software liegt der Fokus in der Regel auf der Skalierbarkeit und der Stabilität bzw. Ausfallsicherheit der Lösung. Da PHP immer mehr im Bereich der Enterprise-Systeme Fuß fasst, ist es kaum verwunderlich, dass auch der Bedarf nach Messaging-Lösungen steigt und sich einige Entwickler bereits mit der Umsetzung beschäftigt haben. Trotzdem steht die Entwicklung hier noch am Anfang und so ist auch die Auswahl an Lösungen noch überschaubar. Im Folgenden werden die derzeit verfügbaren Möglichkeiten aufgezeigt, die PHP-Entwicklern zur Verfügung stehen.
JMS-Bridges
Der JEE-Standard von Sun definiert, dass jeder Java-Application-Server eine Message-Queue-Implementierung mitbringen muss. Aus diesem Grund ist der Einsatz innerhalb von Java-Enterprise-Anwendungen sehr beliebt. Mit JMS (Java Messaging Service) legt der Standard zudem sehr exakt fest, wie die Message Queues verwendet werden. Leider ist dieser Standard primär auf Java-Systeme zugeschnitten, sodass es für PHP-Entwickler nicht gerade einfach ist, auf die Funktionen einer JMS Message Queue zuzugreifen. Grundvoraussetzung für den Einsatz von JMS ist eine funktionstüchtige Installation eines Java-Application-Servers wie JBoss oder GlassFish. Beide bringen eine entsprechende Message-Queue-Implementierung von Haus aus mit.
Wie bereits erwähnt, lässt sich eine JMS-Implementierung nur durch Java mit Nachrichten füllen und auslesen. Glücklicherweise existieren mittlerweile verschiedene Möglichkeiten, wie sich aus PHP heraus Java-Funktionen nutzen lassen. Die wohl populärste ist die Nutzung der PHP/Java Bridge. Diese Open-Source-Erweiterung erlaubt den Zugriff auf die Ressourcen eines JEE-Application-Servers und damit auch den Zugriff auf eine Message Queue. Listing 1 zeigt ein Beispiel hierfür.
Listing 1: Die PHP/Java Bridge erlaubt den Zugriff auf JMS Message Queues
<?php// Setzen der Verbindungsparameter$env = array("java.naming.factory.initial" =>"org.jnp.interfaces.NamingContextFactory","java.naming.factory.url.pkgs" => "org.jboss.naming:org.jnp.interfaces","java.naming.provider.url" => "jnp://queueserver:1099");$ctx = new Java("javax.naming.InitialContext", $env);// Erstellen der Verbindung$queue = $ctx->lookup('queue/mdb');$factory = $ctx->lookup('ConnectionFactory');$con = $factory->createQueueConnection();$session = $con->createQueueSession(false, 1);// Erstellen und Senden der Nachricht$msg = $session->createTextMessage('Testnachricht');$sender = $session->createSender($queue);$sender->send($msg);$session->close();?>
Auf ähnliche Art und Weise funktioniert das Ganze über die PHP/Java Bridge, die in der ES-Version des Platform-Produkts von Zend enthalten ist. Diese kostenpflichtige Lösung ist vor allem für diejenigen interessant, die bereits die Zend Platform einsetzen. Der Einsatz von JMS ist folglich mit einem nicht zu unterschätzenden Aufwand verbunden. Neben der Installation und Konfiguration eines Java-Application-Servers und der Einrichtung der Queue auf diesem System, muss auch die PHP/Java Bridge korrekt installiert sein, um die Java-Klassen aus PHP heraus nutzen zu können. Wer eine einfache und schnell einsetzbare Lösung sucht, ist hier also an der falschen Stelle.
Zum Einsatz ist in der Regel eine Installation eines kompletten Java-Application-Servers notwendig. Diese Lösung hat allerdings dann ihren Reiz, wenn Sie als Nachrichtenkonsumenten Java-Programme einsetzen wollen. Dort kann eine derartige Lösung durch ihre nahtlose Integration ihre Stärken ausspielen. Je nach verwendetem Application-Server sind diese Lösungen auf hohe Last und Stabilität ausgelegt. Viele dieser Queue-Server sind seit Jahren bekannte und ausgereifte Lösungen.
ActiveMQ
ActiveMQ ist eine Message-Queue-Implementierung, die unter dem Dach der Apache-Organisation seit Jahren kontinuierlich weiterentwickelt wird und die sowohl einen beachtlichen Funktionsumfang besitzt als auch als sehr stabiles System bekannt ist. Nicht umsonst kommt ActiveMQ auch in verschiedenen Java-Application-Servern als Message-Queue-Implementierung zum Einsatz. ActiveMQ ist in Java programmiert und demnach erst einmal für den Einsatz mit PHP ungeeignet. Als Subprojekt existiert aber mit Stomp bereits seit einiger Zeit eine Lösung, mit der verschiedenste Programmiersprachen auf ActiveMQ zugreifen können. Listings 2 und 3 zeigen den schreibenden und lesenden Zugriff auf eine Queue über den PHP-Client von Stomp.
Listing 2: Einsatz von Stomp für den schreibenden Zugriff auf eine ActiveMQ Message Queue
<?phprequire_once("Stomp.php");// Verbindungsaufbau$con = new Stomp("tcp://localhost:61613");$con->connect();// senden einer Nachricht an die Queue$con->send("/queue/phpmag", "Testnachricht");// Disconnect$con->disconnect();?>
Listing 3: Einsatz von Stomp für den lesenden Zugriff auf eine Queue
<?phprequire_once("Stomp.php");// Verbindungsaufbau$con = new Stomp("tcp://localhost:61613");$con->connect();// Lesender Zugriff auf eine Queue$con->subscribe("/queue/phpmag");// Nachricht abrufen$msg = $con->readFrame();echo $msg->body;// disconnect$con->disconnect();?>
Der Zugriff auf die Message Queue gestaltet sich damit recht einfach. Die Komplexität wird durch die PHP-Client-Bibliothek vor dem Entwickler verborgen. Wer jedoch auf der Suche nach einer einfachen und schnell einsetzbaren Lösung ist, der wird mit ActiveMQ wahrscheinlich nicht sehr glücklich werden. Der Aufwand für die Inbetriebnahme der ActiveMQ/Stomp-Lösung ist in vielen Fällen hoch. Auch ist die Software recht ressourcenhungrig. Zwar ist der Einsatz von PHP über Stomp möglich, einfach und unkompliziert ist aber wahrscheinlich keines der Attribute, die man der Gesamtlösung geben würde. Der große Vorteil liegt hier in der Möglichkeit, über ActiveMQ auch sehr heterogene Systemlandschaften miteinander verbinden zu können. Auch werden die Nachrichten persistent gespeichert und überstehen somit durchaus auch einen Ausfall des Queue-Servers.



