Hasensymphonie

RabbitMQ zur verteilten Bearbeitung von Aufgaben und Entkopplung von Applikationsteilen
Kommentare

Eine PHP-Webanwendung wird innerhalb eines HTTP-Requests ausgeführt. Ein Request hat eine endliche Laufzeit, die zumeist durch Konfiguration des HTTP-Servers, der Script-Engine oder einer Nutzerinteraktion (z. B. eines Abbruchs) begrenzt ist. Diese „natürliche“ Grenze verhindert die Ausführung von langlaufenden, nebenläufigen oder verknüpften Operationen wie bspw. einem Videoupload, der Ausführung einer Kette von abhängigen Prozessen mit möglichst hoher Ausfallsicherheit in jedem Prozess oder verteiltem Logging.

PHP Magazin

Der Artikel „Hasensymphonie“ von Wolf Bauer und Mike Lohmann ist erstmalig erschienen im PHP Magazin 3.2013

Eine wirkliche parallele und asynchrone Berechnung ist mit dem HTTP-Request-Konzept nicht ohne Weiteres umzusetzen. Die Forderung nach Nebenläufigkeit in der Anwendung wird oft gestellt, wenn zeitintensive Berechnungen oder die Verteilung auf nachgelagerte Systeme die Lösung für fachliche Anforderungen sind. Der Ablauf ist dabei meist sehr ähnlich zu dem dargestellten Beispiel eines Videouploads (Abb. 1).

Abb. 1: Ein Request wird relativ zügig abgearbeitet und stellt in diesem Fall eine zu bearbeitende Datei in ein Verzeichnis ein. Das Bearbeiten der Datei (Encoding) wird aber von einem ganz anderen Prozess übernommen

Dabei hat der Nutzer den Vorteil, dass Berechnungen unabhängig von seinem Upload ausgeführt werden können. Es ist in der Regel nicht wichtig, wann die Berechnung erfolgt, sondern dass der Nutzer, wenn sie erfolgt ist, benachrichtigt wird. Auch in PHP-Applikationen kann mithilfe verschiedener Werkzeuge diese Nebenläufigkeit oder gleichzeitige Ausführung von mehreren Prozessen erreicht werden. In unserem Unternehmen (ICANS GmbH, [1]) setzen wir RabbitMQ [2] als Message Broker ein, um mittels Nachrichten (Messages) Prozesse, die auf unterschiedlichen Systemen laufen, anzustoßen. Dieser Artikel zeigt, wie wir Anforderungen an Nebenläufigkeit mithilfe von RabbitMQ gelöst haben und auftretenden Problemen begegnet sind.

RabbitMQ – Basics

RabbitMQ ist ein in Erlang und auf Basis des OTP-Frameworks [3] implementierter Message Broker. Ein Message Broker verteilt Nachrichten von einem System zum anderen und kann konfiguriert werden, um Nachrichten nach bestimmten Regeln zuzustellen. RabbitMQ kann als programmiersprachenunabhängiges Übergangswerkzeug von einer Applikation zur anderen eingesetzt werden und hilft bei der Entkoppelung verschiedener unabhängiger und möglicherweise verschiedenartiger Applikationen, dem asynchronen Bearbeiten von Aufgaben in einer Prozesskette oder bei der Anwendung des Publish/Subscribe[4]-Patterns.

Ausfallsicherheit und Datenintegrität sind Teil der Architektur von RabbitMQ. So kann zum Beispiel für jede Nachricht entschieden werden, ob der Erhalt vom Empfänger dem sog. Publisher bestätigt werden muss, oder ob ein „Fire and forget“-Verhalten ausreichend ist. Zur Ausfallsicherheit können mehrere Instanzen von RabbitMQ-Server zu einem Cluster zusammengeschaltet werden. Dabei ist ein Ausfall eines einzelnen Servers unproblematisch, da alle Queues auf allen Servern des Clusters gespiegelt werden können. Das Clustermanagement ist dabei so intelligent, dass der Verlust einer Nachricht sehr unwahrscheinlich ist. Als RabbitMQ in unserem Unternehmen Gearman [5] für neue Projekte abgelöst hat, waren unsere Administratoren bei einer Vorstellung der Features von RabbitMQ bezüglich Ausfallsicherheit und Datenintegrität sofort begeistert.

Zur Kommunikation verwendet RabbitMQ das AMQP-Protokoll zwischen Client, Broker und Consumer.

AMQP

Das Advanced Message Queuing Protocol (AMQP, [6]) ist ein binäres programmiersprachenunabhängiges Kommunikationsprotokoll wie zum Beispiel FTP, POP oder IMAP. Es wurde ursprünglich für und von Firmen der Finanzindustrie entwickelt. Es wurde recht schnell deutlich, dass das Protokoll zur Kommunikation von Applikationen über Systemgrenzen hinweg hervorragend geeignet ist. Ein großer Vorteil dabei ist, dass der Produzent einer Nachricht nicht wissen muss, wie viele Konsumenten mit welchem Zweck es gibt.

RabbitMQ ist ein AMQP-Server, der das AMQP-Protokoll v0.9 implementiert. Exchanges, Bindings und Queues werden innerhalb des Brokers genutzt, um eingehende Nachrichten nach zuvor konfigurierten Regeln abzulegen, zu verteilen und zu verarbeiten.

Message Flow

Der Producer erzeugt eine Nachricht mit allen Inhalten und Nachrichtenoptionen, gibt der Nachricht einen Routing Key (mit Ausnahme bei Verwendung der Fanout Exchange) und sendet sie an eine Exchange des Message Brokers. Die Exchange nimmt die Nachricht entgegen und leitet sie abhängig von Kriterien, die in den Bindings definiert sind, sowie den verwendeten Exchange Type an eine oder mehrere Queues weiter. Letztlich kann dann ein Consumer, der auf eine Queue registriert ist, die Nachricht annehmen und verarbeiten (Abb. 2).

Abb. 2: Message Flow

Themen der folgenden Seiten:

  • Exchange Types
  • Fanout Exchange
  • Direct Exchange
  • Topic Exchange
  • Plug-ins
  • Management
  • Shovel
  • RabbitMQ – Nutzungsbeispiele
  • Videoupload
  • Abstraktion von Schritten in einer Chain
  • Verteiltes Logging
  • Symfony2 und RabbitMQ
  • Ein Bundle vorgestellt – OldSound/RabbitMqBundle
  • Probleme und Lösungen mit PHP-Consumern
  • Generelle Probleme
  • Spezifische Probleme mit RabbitMqBundle
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -