AMQP: Das Advanced Message Queuing Protocol vorgestellt
Dienste müssen miteinander kommunizieren können. Informationen werden ausgetauscht, Daten übermittelt. Das klingt für viele einfacher, als es tatsächlich ist, denn bei solchen Gesprächen verschiedener Anwendungen untereinander sind gleich mehrere Schwierigkeiten zu überwinden: Auch in der IT gibt es beispielsweise Sprachbarrieren (in Form von verschiedenen Programmiersprachen) und man muss sich an ein Protokoll halten, damit es nicht zum Chaos kommt.
Eine Lösung verspricht das Advanced Message Queuing Protocol – kurz AMQP: ein gemeinsames Protokoll, das die Informationen über einen Mittler transportieren kann. Wie funktioniert das? Und was kann AMQP noch?
Wofür braucht man AMQP?
Das Advanced Message Queuing Protocol wird seit 2003 entwickelt und stammt ausnahmsweise nicht aus einem dezidierten Tech-Unternehmen, sondern wurde zunächst bei JPMorgan Chase erdacht, einer US-amerikanischen Bank. Dort entschied man sich, das Projekt mit anderen zusammen weiterzugestalten. Neben IT-Unternehmen wie Cisco interessiert sich aber weiterhin vor allem die Finanzbranche für AMQP. Warum ist das so? Weil Zeit dort Geld ist: Die Informationsübermittlung spielt bei einer Bank, einer Kreditkartengesellschaft oder einer Börse eine große Rolle. Hier werden mehrere hunderttausend Nachrichten pro Sekunde ausgetauscht. Kommen Nachrichten zu spät oder gar nicht an, kann das teuer werden.
Da zum damaligen Zeitpunkt kein kommerzielles Produkt in der Lage war, mit den Anforderungen zufriedenstellend zurecht zu kommen, entschied man sich (namentlich Projektleiter John O’Hara) für ein eigenes Protokoll. O’Hara orientierte sich an offenen Standards wie TCP/IP und entschied sich, auch AMQP frei zur Verfügung zu stellen, um so die Entwicklung an dem Protokoll voranzutreiben. Inzwischen arbeitet eine OASIS-Arbeitsgruppe (eine gemeinnützige Organisation) an der Entwicklung des Protokolls.
AMQP löst gleich mehrere Probleme: Zum einen sorgt das Protokoll (in Zusammenarbeit mit einem Messaging Broker) für eine robuste Datenübertragung, zum anderen ermöglicht AMQP, Nachrichten in einer Warteschlange zu lagern. Dies wiederum lässt eine asynchrone Kommunikation zu: Sender und Empfänger müssen nicht im gleichen Rhythmus agieren. Der Empfänger (Konsument) der Nachricht muss die Information nicht direkt annehmen, verarbeiten und dem Sender (Produzenten) den Empfang bestätigen. Stattdessen holt er sich die Nachricht aus der Warteschlange, wenn er Kapazitäten dazu zur Verfügung hat. Das gibt dem Produzenten unterdessen die Möglichkeit weiterzuarbeiten – es entsteht also kein Leerlauf.
Der Erfolg, den das noch relativ junge Protokoll erfährt, hat auch mit der Interoperabilität zu tun. Das Advanced Message Queuing Protocol stellt eine gemeinsame Basis von sich aus her. Das ermöglicht sogar, dass die verschiedenen Anwendungen in unterschiedlichen Programmiersprachen verfasst sein können. Auf diese Weise verständigen sich auch Programme in unterschiedlichen Organisationen problemlos miteinander. Und da AMQP frei zur Verfügung steht, kann jedes Unternehmen das Protokoll ohne zusätzliche Kosten nutzen.
Das P in AMQP steht für Protocol: Ähnlich wie andere Netzwerkprotokolle legt AMQP also ein Regelwerk und eine Syntax für die Kommunikation von zwei oder mehr Teilnehmern fest.
Wie funktioniert AMQP?
Im OSI-Modell agiert AMQP auf der Anwendungsschicht: Es hat damit direkten Kontakt zu den verschiedenen Programmen. Auch IMAP (für E-Mails), FTP (für die Übertragung von Dateien) und IRC (für Instant Messaging) sind auf dieser Schicht aktiv. Zur Übermittlung der Nachrichten setzt das Protokoll auf Mittler – sogenannte Messaging Broker. Diese übernehmen die Verteilung der Nachrichten an verschiedene Empfänger und nach festgelegten Regeln. AMQP regelt auch das Verhalten dieser Vermittlungsserver.
Da es sich bei AMQP um einen offenen Standard handelt, gibt es verschiedene Messaging Broker. Neben Apache Qpid und dem Microsoft Windows Azure Service Bus ist besonders RabbitMQ beliebt.
Das Advanced Message Queuing Protocol bezieht sich also sowohl auf die Kommunikation zwischen den verschiedenen Teilnehmern als auch auf das Verhalten der Broker selbst. Diese enthalten ihre Anweisungen aus den Nachrichten.
Im Kosmos von AMQP gibt es drei Akteure und ein Objekt:
- Die Nachricht ist das Kernelement der ganzen Kommunikation.
- Der Produzent (Producer) erstellt eine Nachricht und versendet diese.
- Der Messaging Broker verteilt die Nachricht nach definierten Regeln in verschiedene Warteschlangen (Queue).
- Der Konsument (Consumer) nimmt sich die Nachricht aus der Warteschlange, auf die er zugreifen kann, und bearbeitet sie.
Im Broker wird die Vermittlung der Nachricht noch einmal aufgebrochen: Die Exchange nimmt die Nachrichten entgegen und routet die Daten in die korrekte Warteschlange. In welche Queue die Nachricht gehört, erfährt die Exchange über das Binding. Man kennt vier verschiedene Arten, wie eine Exchange Nachrichten weiterleitet.
Exchange-Typen
Die erste Art, die Direct Exchange, schickt Nachrichten an genau einen Empfänger und arbeitet dafür mit Routing Keys. Ein solcher Schlüssel wird der Nachricht mitgegeben. Eine Warteschlange wiederum besitzt einen Binding Key. Dieser identifiziert die Queue gegenüber der Exchange. Wenn Routing Key und Binding Key übereinstimmen, kann die Nachricht an die Warteschlange und damit den Empfänger der Nachricht weitergeleitet werden. Es ist auch möglich, dass eine Queue mehrere Binding Keys besitzt und so auch für mehrere Routing Keys in Frage kommt. Andersherum können sich mehrere Queues auch einen Binding Key teilen, was man als Multiple Binding bezeichnet. Die Exchange vervielfältigt die Nachricht und sendet diese an mehrere Empfänger.
Ähnlich funktioniert die Fanout Exchange. Allerdings ignoriert der Broker hierbei den Routing Key vollständig. Stattdessen routet die Exchange eine Nachricht an alle verfügbaren Queues und vervielfältigt die Informationen dabei. Auf eine andere Weise funktioniert die Topic Exchange. Ähnlich zur Direct Exchange werden Routing Key und Binding Keys gegeneinander abgeglichen, aber es muss keine exakte Übereinstimmung vorliegen. Stattdessen verwendet man Platzhalter. So ist es möglich, Nachrichten gezielt für mehrere Queues bereitzustellen.
Die Headers Exchange schließlich agiert statt mit einem Routing Key mit dem Header einer Nachricht. Dort befinden sich Werte, die mit dem Binding abgeglichen werden. Das Argument mit der Bezeichnung x-match bestimmt, ob alle Werte übereinstimmen müssen (Wert: all) oder nur einer dem Binding entsprechen muss (Wert: any). Während ersteres der Direct Exchange entspricht, kann mit letzterem der gleiche Effekt wie bei einer Topic Exchange erzeugt werden.
AMQP-Frames
Ein Frame ist bei AMQP die grundlegende Einheit. Eine Verbindung besteht aus der geordneten Abfolge von Frames. Ordnung bedeutet in diesem Fall, dass der letzte Frame nicht beim Empfänger ankommen darf, bevor nicht auch alle anderen Frames zuvor ihr Ziel erreicht haben. Jeder Frame lässt sich (in der Version 1.0) in drei Segmente unterteilen:
- Frame Header: Dieser obligatorische Header hat eine Größe von 8 Byte. Hier finden sich Informationen, die das Routing der Nachricht bestimmen.
- Extended Header: Dieser Bereich ist optional und hat auch keinen festgelegten Umfang. Er dient dazu, zukünftig den Header um weitere Informationen zu erweitern.
- Frame Body: Im Body befinden sich die eigentlich zu übertragenden Daten. Die Größe ist frei wählbar. Dieser Bereich kann allerdings auch leer bleiben, dann fungiert der Frame nur dazu, die Verbindung aufrechtzuerhalten.
Der Body eines Frames wiederum kann neun verschiedene Formen annehmen:
- open: Verhandelt die Verbindungsparameter zwischen Broker und Client.
- begin: Gibt an, dass eine Verbindung startet.
- attach: Der Nachricht wird ein Link angehängt, der notwendig ist, um den Datentransfer nutzen zu können.
- flow: Ändert den Status eines Links.
- transfer: Mit dem Transfer Frame wird die eigentliche Nachricht übermittelt.
- disposition: Ein Disposition Frame informiert über Änderungen an der Informationslieferung.
- detach: Entfernt den Link.
- end: Gibt an, dass die Verbindung beendet wird.
- close: Beendet die Verbindung und erklärt, dass keine weiteren Frames mehr gesendet werden.
Queues & Messages
Jede Queue hat einen eigenen Namen, der sie gegenüber den anderen Teilnehmern identifiziert. Entweder legt ein Client oder der Broker die Bezeichnung fest. Eine Warteschlange wird durch einen Speicher realisiert. Dieser kann entweder dauerhaft auf einer Festplatte liegen oder flüchtig in einem Arbeitsspeicher. Die dauerhafte Variante garantiert, dass auch nach dem Neustart eines Brokers die Warteschlange weiterhin besteht. Es garantiert aber nicht, dass auch Nachrichten dauerhaft gesichert sind: Hier hängt es von der Nachricht ab, ob diese auch nach einem Neustart noch zur Verfügung stehen.
Was passiert, wenn ein Consumer die Nachricht in der Warteschlange nicht abrufen kann, weil beispielsweise der Client oder die Verbindung zusammengebrochen ist? Man kann entscheiden, ob ein Consumer den Erhalt einer Nachricht ordentlich quittieren muss oder die reine Auslieferung zum Erfolg ausreicht. Sollte die erste Variante gewählt werden und der Consumer keine Nachricht zurücksenden, versucht der Broker die Nachricht an einen anderen Consumer zu senden oder den eigentlichen Empfänger erneut zu erreichen. Ist allerdings die Variante ohne Bestätigung eingeschaltet und der Consumer ruft die Nachricht nicht ab, geht diese verloren.
Es ist aber auch möglich, dass ein Client die Annahme einer Nachricht bewusst ablehnt. Dies kann sinnvoll sein, wenn die Verarbeitung der Nachricht nicht funktioniert. Die Rückmeldung des Consumers veranlasst den Broker, die Nachricht entweder komplett zu löschen oder erneut in die Warteschlange einzugliedern.
AMQP nutzt Port 5672.
AMQP 1.0 vs. 0-9-1
Es gibt derzeit zwei vollständig unabhängige Versionen des Advanced Message Queuing Protocols. Die Version 1.0 wird von der OASIS-Gruppe entwickelt. Besonders bei RabbitMQ kommt aber die etwas ältere Fassung 0-9-1 zum Einsatz. Beide sind nicht miteinander kompatibel. Die 1.0-Fassung unterscheidet sich in erster Linie durch die geminderte Bedeutung von Brokern, Bindings und Exchanges. 0-9-1 benötigt diese nicht, verbietet es aber auch nicht, solche Mittelsmänner einzusetzen.