Enterprise Middleware mit ActiveMQ
Artikel erschienen in Swiss IT Magazine 2007/14
Moderne Geschäftsarchitekturen zeichnen sich häufig dadurch aus, dass verschiedenste IT-Services über mehrere Standorte integriert werden müssen. Dabei müssen einerseits Legacy-Systeme mit neuen integriert, aber auch neue Services modernen Architekturparadigmen folgend flexibel, wiederverwendbar, skalierbar und performant implementiert werden.
Um diese Ziele zu erreichen, entstanden Architektur-Strategien wie Service-orientierte (SOA) oder ereignisgetriebene Architektur (EDA), aber auch Technologien wie asynchrone nachrichtenorientierte Middleware (Message Oriented Middleware, kurz MOM) und Enterprise Service Bus (ESB). Typischerweise assoziiert man mit diesen Technologien Namen wie IBM MQ-Series, Tibco oder Sonic. Also durchwegs äusserst hochpreisige Softwarelösungen.
Tatsächlich sind in den letzten Jahren aber einige sehr interessante Open-Source-Projekte in diesem Umfeld entstanden, die in einer kleinen Serie betrachtet werden sollen. An erster Stelle steht ein schon relativ alter Bekannter: Apache ActiveMQ. Dieses Projekt implementiert den Java JMS Standard und ist ein JMS-basierter Enterprise Message Broker. Es gehört also in die Kategorie der nachrichtenorientierten Middleware (MOM).
Was zeichnet eine nachrichtenorientierte Middleware aus? Allgemein gesagt dienen Broker zur Verbesserung der «Connectivity», also dem einfacheren Verbinden von Systemen, die sonst nicht ohne weiteres zusammenarbeiten oder die man gerne entkoppelt betreiben möchte. Auf dieser Ebene werden Message Broker häufig auch von Enterprise-Service-Bus-Systemen unterstützt.
Die Aufgabe eines Message Broker ist es, Nachrichten von sendenden Systemen zu empfangen und an die gewünschten Empfänger weiterzuleiten. Das Prinzip gleicht dem eines E-Mail- oder Instant-Messaging-Servers. Da Message Broker wie ActiveMQ eine Schlüsselfunktion in der IT-Architektur einnehmen, müssen sie sehr zuverlässig arbeiten und viele verschiedene (Architektur-)Szenarien unterstützen. Der Hauptgrund für den Einsatz eines Message Broker ist Reliable Messaging: Dabei muss garantiert werden, dass eine Nachricht, die der Broker übernommen hat, auch zugestellt wird. Ebenso hilft ein Broker bei Load Balancing und Redundanz: Ein System kann eine Nachricht an ein «Zielsystem» senden, hinter dem tatsächlich (vom Broker vermittelt) eine ganze Reihe von gleichartigen Systemen steht, auf welche die Last verteilt wird oder die für ausgefallene Systeme einspringen können.
Service-orientierte Architekturen (SOA) sind in aller Munde und werden oft als Architektur-Paradigma für moderne Geschäftsanwendungen gesehen. Häufig werden SOAs mit Webservice-Technologien wie SOAP umgesetzt. Damit hat man zwar Services mit plattformunabhängigen Mechanismen beschrieben, ein wichtiger Punkt von SOAs – die lose Kopplung – lässt sich jedoch mit diesen Standards noch nicht umsetzen. Der UDDI-Standard wird zwar immer wieder in diesem Kontext erwähnt, hat aber kaum nennenswerte Verbreitung gefunden.
Was versteht man nun unter «loser Kopplung»? Verschiedene Services sollen so wenig voneinander wissen wie möglich. Benötigt ein Bestellsystem beispielsweise Informationen über den Lagerbestand eines Artikels, so könnte ein Service existieren, der mit WSDL beschrieben ist, der eben die Abfrage des Lagerbestandes eines bestimmten Artikels erlaubt. Nun ist es aber oft weniger günstig, wenn Clients direkt mit einem bestimmten Server kommunizieren, auf dem dieser Service implementiert ist. Dies wäre eine sehr enge Kopplung und könnte verschiedene Nachteile haben:
Der heute vermutlich bedeutendste Messaging-Standard ist JMS (Java Message Service) von Sun. Der Standard war in den letzten Jahren so erfolgreich, dass es mittlerweile APIs für alle wesentlichen Sprachen gibt, beispielsweise auch für C++ oder .Net. Die Prinzipien von JMS lassen sich verkürzt wie folgt zusammenfassen:
- Es gibt Sender und Empfänger, die übers Netzwerk erreichbar sind.
Eine JMS-Nachricht besitzt im wesentlichen einen Header mit verschiedenen definierten Feldern wie Message ID oder Priority. Dazu kommen Message Properties, in denen beliebige Key-Value-Datenpaare abgelegt werden können. Dies kann für Meta-Informationen oder überhaupt als Datenspeicher für einfache Nachrichten dienen. Schliesslich gibt es noch den Message Body, in dem die eigentliche Nachricht abgelegt wird. Meist geschieht dies als Text respektive XML, möglich sind aber auch Binärdaten, Java-Objekte und andere unübliche Formate.
Der Austausch der Nachrichten erfolgt dabei entweder über eine Queue oder ein Topic. Der Unterschied ist einfach erklärt: Sendet ein Sender an eine Queue, so erhält genau ein Empfänger diese Nachricht. Sendet er hingegen an ein Topic, so können beliebig viele Empfänger diese Nachricht erhalten. Letzterer Fall wird auch als Publish/Subscribe-Mechanismus bezeichnet, bei dem alle die Nachricht erhalten, die ein bestimmtes Topic «abonniert» haben. Dies ist eine sehr elegante Art der Entkoppelung, da der Sender nicht wissen muss, wer eine bestimmte Nachricht empfängt. Auf diese Weise erhält man eine ereignis-getriebene und stark asynchron-entkoppelte Architektur.
Auch die Zuverlässigkeit und die Art der Nachrichtenzustellung, beispielsweise für Transaktionen, sind im JMS-Standard beschrieben:
- Zustellung muss vom Empfänger bestätigt werden oder «auto-acknowledge».
- Zustellung soll transaktional erfolgen.
- Nachrichten sollen nur zugestellt werden, wenn der Client online ist.
- Nachrichten sollen auch zugestellt werden, wenn der Client offline ist (durable queues).
- Der Message Broker soll Nachrichten persistieren. Es darf im Failover-Fall nichts verlorengehen.
- Nachrichten haben Prioritäten, Lebenszeiten usw.
Ein Message Bus auf JMS-Basis ist also der «One-Stop-Information-Shop» des Unternehmens.
Apache ActiveMQ ist eine sehr stabile und leistungsfähige, gleichzeitig recht einfach zu verwendende Open-Source-Implementierung des JMS-Standards, deren Funktionalität jedoch noch weit über die Kern-JMS-Features hinausgeht. Die oben genannten Features werden natürlich unterstützt, daneben bietet ActiveMQ Erweiterungen der Messaging-Funktionalität wie Message Group. Mit diesen können Gruppen von Nachrichten definiert werden, die trotz Load Balancing immer an einen bestimmten Empfänger gesandt werden. Ähnlich arbeiten Composite und Virtual Destinations. Subskriptionen können über Wildcards erfolgen. Man kann sich beispielsweise an eine Gruppe von Topics gleichzeitig anmelden. Auch die Security-Features können sich sehen lassen: Verschiedene Varianten der Authentifizierung und Autorisierung werden angeboten. Autorisierung kann sogar auf Message-Ebene erfolgen. Beide können über Plug-ins erweitert werden.
ActiveMQ-Server können auch im Cluster betrieben werden. Das Management erfolgt über den JMX-Standard (Java Management Extension) und beliebige JMX-Clients. Dazu besitzt die neue Version eine einfache Web-Applikation, mit der Topics und Queues überwacht sowie Nachrichten versandt werden können. Der Web-Client ist nicht sehr umfassend, aber man kann wohl davon ausgehen, dass die Funktionalität in Zukunft erweitert wird. Besonders für den Einstieg ist er jedoch sehr hilfreich, weil er in der Standardkonfiguration automatisch startet und hilft, die ersten Messaging-Schritte nachzuvollziehen.
ActiveMQ kann mit verschiedensten Systemen integriert werden, beispielsweise mit Komponentenframeworks wie Spring, J2EE-Implementierungen wie Apache Geronimo oder JBoss sowie Enterprise-Service-Bus-Lösungen wie Mule oder Service Mix. Dazu bietet es APIs für eine Vielzahl an Sprachen wie .Net, C#, Delphi, Flash, JavaScript, Perl, PHP, Python, Ruby und andere. Auch verschiedene Nicht-JMS-Protokolle werden unterstützt, unter anderem etwa REST, RSS, Atom, XMPP (Jabber Instant Messaging) und Stomp.
Die Stomp-Integration ist sehr hilfreich, wenn man Systeme, die noch keinen verwendbaren Konnektor haben, an ActiveMQ andokken möchte. Stomp ist ein einfach zu implementierendes Text-basiertes Protokoll, auf dessen Basis sich auch Konnektoren für Legacy-Systeme aller Art schreiben lassen.
Im Umfeld von ActiveMQ gibt es eine Vielzahl an kleineren und grösseren Projekten, die sich teilweise auch im Apache-Umfeld befinden wie Camel, CMS und NMS. Die letzteren beiden implementieren APIs für C++ und .Net. Besonders interessant ist das recht neue Camel. Camel implementiert die meisten von Gregor Hohpe beschriebenen Enterprise Integration Patterns, unter anderem Pipes und Filter, Content-based Router und Splitter. Mit Hilfe von Camel kann man daher viele in der Integration von Anwendungen häufig vorkommende Muster sehr leicht abbilden und darauf aufbauend Anwendungen entwickeln. Camel arbeitet mit beliebigen JMS-Brokern, ist aber (naturgemäss) sehr gut mit ActiveMQ integriert.
Andere ActiveMQ-bezogene Projekte wie Stomp, Lingo oder Jencks, die hier nicht mehr im Detail beschrieben werden können, finden sich teilweise im Codehaus-Projektpool.
ActiveMQ ist eine leistungsfähige und stabile JMS-Message-Broker-Implementierung mit «gesunder» Community und einer Vielzahl an grösseren und kleineren «Satelliten-Projekten», die um ActiveMQ kreisen. ActiveMQ kann ein wesentlicher Baustein in einer modernen Enterprise-Architektur darstellen und verträgt sich gut mit vielen anderen Systemen wie ESBs oder J2EE-Containern.
Die Lernkurve bei ActiveMQ ist eigentlich nicht sehr hoch, wenn man das Konzept des asynchronen Messaging erst einmal verstanden hat. Allerdings kann die Vielzahl an verwandten Projekten dann doch etwas verwirren. Dies ist allerdings kein Problem von ActiveMQ alleine. Auch kommerzielle Umgebungen wie Websphere oder Sonic verfügen mittlerweile über eine Unzahl an Komponenten, bei denen es nicht immer einfach ist, den Überblick zu behalten.
Es muss jedoch klar sein, dass Systeme wie ActiveMQ im Produktiv-Betrieb Kernkomponenten einer IT-Architektur darstellen und daher sehr gut verstanden werden sollten (Konfiguration, Wartung, Betrieb).
Nicht ganz ideal ist die Dokumentation zu ActiveMQ. Das Problem ist allerdings nicht so sehr das fehlende Material als vielmehr die mangelhafte Strukturierung. Im Endeffekt findet man (fast) alles, was man sucht, nur leider ist die Organisation des Materials nicht ideal. Es gibt auch noch kein Buch zu ActiveMQ (sehr wohl aber zu JMS und den Enterprise Integration Patterns). Die Community ist aber lebendig und die Mailingliste im Falle von Detailproblemen immer hilfreich.
Stack
1. Active MQ herunterladen und entpacken.
2. Voraussetzungen prüfen: Java-Umgebung muss installiert sein.
3. Kommandozeile öffnen und ins «bin» Verzeichnis wechseln
4. ./activemq starten (Unix, Mac OS X)
ActiveMQ startet dann in einer Standard-Konfiguration, die für erste Experimente mit Sicherheit ausreichend ist. Die neueren Beta-Versionen sowie Snapshots haben auch schon eine einfache Web-Konsole dabei, die unter
http://0.0.0.0:8161/admin zu finden ist (siehe Screenshot auf Seite 46). Unter http://0.0.0.0:8161/demo/ sind ein paar Beispielanwendungen zu finden. Für den operativen Betrieb sollte man natürlich die Konfigurationsmöglichkeiten genauer studieren und entsprechend anpassen.
Alexander Schatten (alexander@schatten.info) ist Assistent am Institut für Softwaretechnik und interaktive Systeme der Technischen Universität Wien.