RabbitMQ zur verteilten Bearbeitung von Aufgaben und Entkopplung von Applikationsteilen
Kommentare

Shovel
Mittels des Shovel-Plug-ins ist es möglich, Nachrichten einer Queue eines Brokers – die sog. source – auf eine Exchange eines anderen Brokers – die sog. destination – zu transferieren. Das Plug-in

Shovel

Mittels des Shovel-Plug-ins ist es möglich, Nachrichten einer Queue eines Brokers – die sog. source – auf eine Exchange eines anderen Brokers – die sog. destination – zu transferieren. Das Plug-in ist ebenfalls in der Standarddistribution von RabbitMQ enthalten und kann über rabbitmq-plugins enable rabbitmq_shovel aktiviert werden. Zusätzlich kann das rabbitmq_shovel_management-Plug-in aktiviert werden, das eine einfache Statusanzeige der konfigurierten Shovels in der Managementoberfläche anbietet [10]. Allerdings wird leider nicht die komplette Konfiguration der Shovels angezeigt, was die Fehlersuche erschwert, da diese nur in den Konfigurationsdateien eingesehen werden kann.

Shovels ermöglichen eine hohe Entkoppelung von Systemkomponenten. Produziert eine Webanwendung bspw. Log-Messages, entstehen potenziell sehr große Datenmengen. Sollen diese verarbeitet werden, macht es Sinn, sie in einem separaten System abzuarbeiten, das aus Sicherheitsgründen ggf. in einem separaten Netzwerk läuft. Nun kann die Webanwendung Nachrichten bei einem lokalen Broker publizieren, die durch eine Shovel in einen Broker in dem Zielnetzwerk weitergeleitet werden.

RabbitMQ – Nutzungsbeispiele

Wie zuvor erwähnt, wird RabbitMQ bei der ICANS GmbH in diversen Systemen als Message Broker genutzt. Um eine Vorstellung der Möglichkeiten von RabbitMQ zu bekommen, werden im Folgenden nun einige Beispiele für einen Einsatz vorgestellt. Zunächst wird der Upload von Videos betrachtet und anschließend eine Abstraktion von aufeinanderfolgenden Prozessschritten beschrieben, die eine nebenläufige Verarbeitung von Reports erlaubt. Abschließend wird ein verteiltes Logging basierend auf RabbitMQ vorgestellt.

Videoupload

Werden auf einer Webseite Videos verwendet, besteht in der Regel der Wunsch, sie in einem einheitlichen Format vorliegen zu haben. Wird Nutzern die Möglichkeit gegeben, eigene Videos hochzuladen, kann dies in sehr unterschiedlichen Formaten geschehen, die in das einheitliche Format umgewandelt werden müssen. Um zudem eine hohe Verfügbarkeit der Videos zu gewährleisten und beim Streamen Last von den eigenen Server zu nehmen, bietet sich zudem die Nutzung von Cloud-Diensten wie Amazon S3 [11] an.

Soll dieser Anwendungsfall umgesetzt werden, wird deutlich, dass die Encodierung und der Upload von Videos zu Drittanbietern enorme Zeit in Anspruch nehmen kann. Es ist klar, dass ein Webseitennutzer nach dem Videoupload nicht auf eine sequenzielle Abarbeitung warten kann. Um dies dennoch umzusetzen, bietet sich eine parallele Verarbeitung der Videodaten an: Lädt ein Nutzer ein Video hoch, kann diesem, nachdem innerhalb der PHP-Anwendung alle relevanten Videodaten gespeichert und eine Nachricht an einem RabbitMQ Broker versendet wurden, mitgeteilt werden, dass er benachrichtigt wird, sobald sein Video verfügbar ist. In einem parallel zur Webanwendung laufenden Consumer kann nun das Video verarbeitet und auf den Drittanbieter verteilt werden. Nach der Verarbeitung kann der Nutzer benachrichtigt werden, dass sein Video verfügbar ist.

Durch diese Architektur kann Last von der Webseite genommen werden, und der Nutzer kann ohne Wartezeiten weiterarbeiten. Zudem wäre es möglich, zu Spitzenzeiten, in denen viele Videos verarbeitet werden müssen, mehrere Consumer parallel laufen zu lassen.

Abstraktion von Schritten in einer Chain

Sollen Daten externer Partner verarbeitet werden, gibt es in der Regel immer wiederkehrende Herausforderungen. Vereinfacht können diese in einer Abfolge von Verarbeitungsschritten abgebildet werden. Dabei müssen Daten beim Partner extrahiert und in ein internes Format encodiert werden. Anschließend können Datenvalidierungen sowie Plausibilitätsprüfungen durchgeführt werden, um die Daten abschließend je nach Bedarf verarbeiten zu können. Einzelne Schritte können je nach Daten aufwendiger sein als andere und somit die Verarbeitung blockieren.

Betrachtet man die einzelnen Schritte als vollständig entkoppelte Anwendungen, kann dies durch den Einsatz von RabbitMQ verhindert werden. Hierbei laufen die einzelnen Anwendungen als eigenständige Instanzen und kommunizieren mittels Messages mit den jeweils vor- bzw. nachgelagerten Verarbeitungseinheiten. Hat die Extraktion Daten eingelesen, wird anschließend eine Nachricht an die Encoding-Queue gesendet. Diese kann durch eine Encoding-Instanz verarbeitet werden, die anschließend wiederum eine Nachricht in der nächsten Queue publiziert usw.
Diese Entkoppelung ermöglicht eine nebenläufige Verarbeitung von Programmlogiken. Ist bspw. bekannt, dass die Plausibilitätsprüfung ein langläufiger Prozess ist, können einfach mehrere solcher Instanzen dieses Schritts gestartet werden, wobei jede Instanz eine Nachricht der vorherigen Queue selbstständig verarbeiten kann.

Verteiltes Logging

Businesskritische Entscheidungen basieren in allen Geschäftsbereichen auf einer komplexen Analyse von gesammelten Daten. Dies gilt auch für professionelle Webapplikationen, für die Entscheidungen von Stakeholdern getroffen werden. Die Grundlage für diese Entscheidungen bilden Nutzungsdaten der Kunden der Webapplikationen. Ein sehr bekanntes Beispiel ist die Analyse des Kaufabbruchs bei großen Onlineshops. Der Prozess des Kaufens wird, basierend auf den Daten zum Kaufabbruch, so weit optimiert, dass die Zahl der Kaufabbrüche geringer wird. Zusätzlich zu den Nutzungsdaten sind auch Fehlerdaten interessant. Diese sammeln und analysieren zu können, ist für das Bugfixing und die Weiterentwicklung der Webapplikation immens wichtig. In beiden Fällen darf die Auslieferungszeit der Seite nicht großartig beeinträchtigt werden.

Innerhalb von Symfony2 steht mit Monolog [12] ein umfangreicher Logger zur Verfügung, der so erweitert werden kann, dass ein Logging zu RabbitMQ möglich ist. Damit kann dann eine RabbitMQ-Instanz auf jedem Webserver laufen und die Applikation schnell zum lokalen Broker loggen. Dieser wiederum verwendet ein Plug-in (Shovel), um die Lognachrichten zu einer zentralen RabbitMQ-Instanz (Cluster) weiterzuleiten. Daran sind dann Consumer angeschlossen, die die Daten entsprechend weiterverarbeiten können, um zum Beispiel Fehlernachrichten in eine zentrale Graylog-Instanz zu senden oder im HDFS abzulegen, damit man später die Daten per MapReduce analysieren kann.

Für einen Request sollen zusätzlich möglichst alle Daten zusammengefasst werden können, damit Bugfixing und die Zuordnung von Aktionen zu Usern einfacher ist. Innerhalb der ICANS GmbH verwenden wir dafür eine so genannte Pulse-ID [13], die in einem dem Kunden sehr nahen System (Load Balancer) erstellt wird und sich durch alle Server-(Apache, MySQL, MongoDB, elasticsearch usw.) und Applikations-Logs hindurchzieht. Anhand dieser sind dann alle Aktionen und ggf. Probleme einem Request zuzuordnen.

Verschiedene Produzenten können nun diese Pulse-ID nutzen, mit im Message-Body einfügen und über einen AMQP-Client eine Nachricht an eine lokale RabbitMQ-Instanz senden.

Der Vorteil dabei ist, dass sowohl Fehler-Logging als auch Event-Logging von jedem System über ein- und dasselbe Protokoll erfolgt. Das heißt, dass es nur eine Logging-Infrastruktur [14] für alle Arten von Log-Nachrichten gibt (Abb. 7).

Abb. 7: Logging-Infrastruktur

Themen der folgenden Seiten:

  • 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 -