Další implementací message brokeru, s níž se seznámíme, je nástroj nazvaný Apache ActiveMQ. Dnes si ukážeme jeho instalaci, základní metody komunikace s ním a také utility pro sledování a ovládání tohoto nástroje.
Další implementací message brokeru, s níž se seznámíme, je nástroj nazvaný Apache ActiveMQ. Dnes si ukážeme jeho instalaci, základní metody komunikace s ním a také utility pro sledování a ovládání tohoto nástroje.
1. Apache ActiveMQ – další systém implementující message brokera
2. Protokoly podporované systémem Apache ActiveMQ
4. Základní příkazy podporované nástrojem activemq
5. Použití nástroje activemq pro poslání popř. pro přijetí zprávy
6. Komunikační protokol STOMP a knihovna stomp.py
7. Jednoduchý producent zpráv naprogramovaný v Pythonu
8. Konzument zpráv naprogramovaný taktéž v Pythonu
11. Webové rozhraní Apache ActiveMQ
12. Přístup k nastavení a stavu Apache ActiveMQ s využitím nástroje JConsole
13. Ukázka komunikace s Apache ActiveMQ s využitím telnetu přes protokol STOMP
14. Připojení a poslání zprávy do fronty
15. Další příkazy podporované protokolem STOMP
16. Od Apache ActiveMQ k Red Hat AMQ
17. Součásti (komponenty) systému Red Hat AMQ
18. Repositář s demonstračními příklady
19. Odkazy na předchozí části seriálu
V dnešním článku si ukážeme základní práci s message brokerem nazvaným Apache ActiveMQ (neboli zkráceně Apache AMQ). Tento systém je naprogramován v Javě (i když obsahuje i jednu nativní knihovnu), podporuje velké množství komunikačních protokolů (včetně AMQP a STOMPu) a nabízí poměrně široké možnosti konfigurace. Pro práci s tímto message brokerem využijeme protokol STOMP a knihovnu stomp.py určenou pro jazyk Python 2 a samozřejmě i Python 3. Tato knihovna podporuje obě nejpoužívanější komunikační strategie: PUB-SUB i PUSH-PULL (s frontami), popř. lze nakonfigurovat směrování zpráv a dokonce i jejich persistenci (uložení do různých typů databází, což je téma, které si popíšeme příště).
Se systémem Apache ActiveMQ je možné komunikovat pomocí několika protokolů. Některé protokoly, typicky ty, které jsou navrženy právě pro message brokery, se používají jak pro posílání zpráv, tak i pro jejich příjem. Další protokoly jsou zaměřeny pouze pro komunikaci jedním směrem, například pro informaci zaregistrovaných klientů o tom, že je k dispozici nějaká zpráva. V následující tabulce jsou jednotlivé protokoly vypsány, přičemž pro klasické message brokery nás budou zajímat především první tři řádky tabulky:
Zkratka | Protokol |
---|---|
AMQP 1.0 | Advanced Message Queuing Protocol verze 1.0 |
STOMP | Streaming Text Oriented Messaging Protocol |
MQTT | MQTT is a machine-to-machine connectivity protocol |
OpenWire | tato zajímavá technologie bude popsána v samostatném článku |
REST | Representational state transfer |
RSS a Atom | RDF Site Summary, informace klientů se zprávou |
WSIF | Web Services Invocation Framework |
WS Notification | |
XMPP | Extensible Messaging and Presence Protocol |
AUTO | viz poznámka pod tabulkou |
V enterprise sféře je pravděpodobně nejpoužívanějším protokolem pro message brokery protokol AMQP (Advanced Message Queuing Protocol), s nímž jsme se již částečně setkali při popisu systému RabbitMQ. Ovšem zatímco RabbitMQ podporuje starší verze 0.9.1, 0.9 a 0.8, je tomu v případě Apache MQ jinak, protože je podporován novější protokol verze 1.0 (ten se od předchozích variant liší svou sémantikou i vlastní binárním formátem). Jedná se o binární protokol, v němž je velká váha kladena nejen na precizní specifikaci formátu dat, ale i na popis sémantiky operací prováděných službami, které AMQP implementují (či možná lépe řečeno akceptují).
Dalším důležitým protokolem, který lze použít pro komunikaci s Apache MQ, je protokol nazvaný STOMP neboli Streaming Text Oriented Messaging Protocol. Jedná se o relativně jednoduchý protokol založený – jak jeho název napovídá – na příkazech posílaných v textovém formátu se syntaxí, která se podobá protokolu HTTP. Předností STOMPu je snadná implementace klientů a v případě potřeby (ladění, simulace útoků atd.) je dokonce možné namísto dedikovaného klienta použít běžný nástroj telnet, což si ostatně ukážeme ve čtrnácté kapitole. Ve výchozím nastavení existuje omezení maximální délky zprávy na 10 MB, ovšem tuto hodnotu je možné v případě potřeby změnit.
Třetím užitečným protokolem, o němž se ve stručnosti zmíníme a který je systémem Apache ActiveMQ podporován, je protokol nazvaný MQTT, který je mj. určený pro dnes populární IoT, tj. obecně pro zařízení s relativně malým výkonem popř. omezenými systémovými zdroji (a většinou i omezenou odolností proti útokům :).
Systém Apache ActiveMQ je z větší části naprogramován v Javě (kromě knihovny wrapper a dalších maličkostí) a vyžaduje, aby na systému byla nainstalována JRE (Java Runtime Environment) Javy 8, což by na většině současných systémů nemělo být problematické zajistit (navíc je možné v případě potřeby provést překlad i pro JRE Javy 7). Instalace je ve skutečnosti velmi snadná a spočívá se stažení a rozbalení jednoho tarballu. Poslední stabilní verzí Apache ActiveMQ je verze 5.18 a stáhneme ji buď běžným webovým prohlížečem nebo přímo z příkazové řádky tímto příkazem:
$ wget -O apache-activemq-5.15.8-bin.tar.gz "http://www.apache.org/dyn/closer.cgi?filename=/activemq/5.15.8/apache-activemq-5.15.8-bin.tar.gz&action=download"
Dále musíme získaný tarball, jehož velikost přesahuje 50 MB, rozbalit příkazem:
$ tar xvfz apache-activemq-5.15.8-bin.tar.gz ... ... ...
Nyní si otestujeme, zda je možné spustit základní nástroj activemq, který je umístěný v podadresáři bin:
$ cd apache-activemq-5.15.8/bin/
Zkusíme si zobrazit nápovědu se základními podporovanými příkazy:
$ ./activemq help Usage: Main [--extdir <dir>] [task] [task-options] [task data] Tasks: browse - Display selected messages in a specified destination. bstat - Performs a predefined query that displays useful statistics regarding the specified broker consumer - Receives messages from the broker create - Creates a runnable broker instance in the specified path. decrypt - Decrypts given text dstat - Performs a predefined query that displays useful tabular statistics regarding the specified destination type encrypt - Encrypts given text export - Exports a stopped brokers data files to an archive file list - Lists all available brokers in the specified JMX context producer - Sends messages to the broker purge - Delete selected destination's messages that matches the message selector query - Display selected broker component's attributes and statistics. start - Creates and starts a broker using a configuration file, or a broker URI. stop - Stops a running broker specified by the broker name. Task Options (Options specific to each task): --extdir <dir> - Add the jar files in the directory to the classpath. --version - Display the version information. -h,-?,--help - Display this help information. To display task specific help, use Main [task] -h,-?,--help Task Data: - Information needed by each specific task. JMX system property options: -Dactivemq.jmx.url=<jmx service uri> (default is: 'service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi') -Dactivemq.jmx.user=<user name> -Dactivemq.jmx.password=<password>
Ukažme si ve stručnosti ty nejzákladnější příkazy, které jsou nástrojem activemq podporovány.
Spuštění služby ActiveMQ na pozadí:
$ ./activemq start INFO: Loading '/home/tester/apache-activemq-5.15.8//bin/env' INFO: Using java '/usr/bin/java' INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details INFO: pidfile created : '/home/tester/apache-activemq-5.15.8//data/activemq.pid' (pid '9114')
Spuštění služby ActiveMQ na popředí (všechny zprávy se budou vypisovat na terminál):
$ ./activemq console ... ... ...
Ukončení běžící služby ActiveMQ:
$ ./activemq stop Connecting to pid: 20378 Stopping broker: localhost . TERMINATED
Výpis dostupných brokerů:
$ ./activemq list Connecting to pid: 19789 brokerName = localhost
Dtto, ovšem ve chvíli, kdy je služba pozastavena:
$ ./activemq list INFO: Broker not available at: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
Nástroj activemq může být dokonce použit i pro poslání popř. pro přijetí zprávy. Ve skutečnosti se zdaleka nejedná o ten nejrychlejší způsob, jak s ActiveMQ pracovat, ovšem je zdaleka nejjednodušší. V příkladech se použije výchozí fronta nazvaná „queue://TEST“.
Poslání stovky shodných zpráv „Hello world“:
$ ./activemq producer --message "Hello world"
Poslání jediné zprávy „Hello world“:
$ ./activemq producer --message "Hello world" --messageCount 1
Poslání zprávy, jejímž tělem jsou data získaná z určité URL. Následující příklad je jen umělý, ve skutečnosti se spíše bude volat nějaké REST API pro získání dat:
$ ./activemq producer --payloadUrl https://www.root.cz --messageCount 1
A nakonec spustíme konzumenta zpráv, při jehož spuštění je možné určit, zda se má zpracování provést v transakci či nikoli:
$ ./activemq consumer --transacted true ... ... ... INFO | consumer-1 Received Hello INFO | consumer-1 Committing transaction: 99 INFO | consumer-1 Consumed: 1000 messages INFO | consumer-1 Consumer thread finished
V dnešních demonstračních příkladech použijeme pro komunikaci klientů se systémem Apache ActiveMQ protokol STOMP, o němž jsme se ve stručnosti zmínili v úvodních kapitolách. Příklady budou – podobně jako v předchozích částech tohoto seriálu – naprogramovány v jazyku Python, takže nejdříve nainstalujeme knihovnu nazvanou stomp.py zajišťující rozhraní k jakémukoli message brokerovi, který tento protokol využívá, samozřejmě včetně Apache ActiveMQ. Tato knihovna existuje jak pro Python 2.x, tak i pro Python 3.x a podporuje všechny v současnosti dostupné verze protokolu STOMP: 1.0, 1.0 i 1.2.
Instalace této knihovny je snadná, protože ji nalezneme v PyPi. Pro jednoduchost bude instalace provedena pro právě přihlášeného uživatele:
$ pip3 install --user stomp-py Collecting stomp-py Downloading https://files.pythonhosted.org/packages/80/c8/d13f0058ede2d83e54028cbad98a5886aaf2501017ddf4231ec1deff81b3/stomp.py-4.1.15-py2.py3-none-any.whl Installing collected packages: stomp-py Successfully installed stomp-py
Základní test, zda se instalace podařila, lze provést přímo z interpretru Pythonu:
$ python3 Python 3.6.3 (default, Oct 9 2017, 12:11:29) [GCC 7.2.1 20170915 (Red Hat 7.2.1-2)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import stomp >>> help("stomp") Help on package stomp: NAME stomp DESCRIPTION stomp.py provides connectivity to a message broker supporting the STOMP protocol. Protocol versions 1.0, 1.1 and 1.2 are supported. See the GITHUB project page for more information. Author: Jason R Briggs License: http://www.apache.org/licenses/LICENSE-2.0 ... ... ...
Kromě vlastní knihovny stomp-py se nainstaluje i jednoduchý klient ovládaný z příkazového řádku. Tento klient se jmenuje jednoduše stomp a můžeme si vyzkoušet jeho základní funkce:
$ stomp --version Stomp.py Version 4.1.21
Zkusíme se připojit k lokálně běžící instanci Apache ActiveMQ (viz předchozí kapitolu):
$ stomp CONNECTED server: ActiveMQ/5.15.8 heart-beat: 0,0 session: ID:localhost.localdomain-38215-1549567803551-3:3 version: 1.1 > >
Výpis základních příkazů:
help Documented commands (type help <topic>): ======================================== EOF begin help rollback sendfile stats ver abort commit nack run sendrec subscribe version ack exit quit send sendreply unsubscribe
Poslání zprávy do fronty nazvané „test“:
send /queue/test hello world MESSAGE content-length: 11 expires: 0 destination: /queue/test
Přihlášení se k odběru zpráv z fronty „test“:
subscribe /queue/test Subscribing to "/queue/test" with acknowledge set to "auto", id set to "1" subscription: 1 priority: 4 message-id: ID:localhost.localdomain-38215-1549567803551-3:3:-1:1:1 timestamp: 1549631641256 hello world
Zkusme si nyní naprogramovat jednoduchého producenta zpráv, které budou do message brokera poslány s využitím komunikační strategie PUB-SUB. To znamená, že pokud bude existovat nějaký klient naslouchající těmto zprávám, budou mu poslány. V případě, že bude naslouchat více klientů, budou zprávy rozeslány všem těmto klientům a pokud nebude připojen ani jeden klient, bude zpráva zahozena.
Nejprve musíme zajistit připojení k Apache ActiveMQ běžící na stejném počítači. Pro protokol STOMP by měl být otevřený výchozí port 61613:
conn = stomp.Connection(host_and_ports=[("localhost", 61613)]) conn.start()
Výchozí přihlašovací jméno a heslo je „admin“/„admin“ (i když v dokumentaci je psáno „password“):
conn.connect(login="admin", passcode="admin")
Zprávy se posílají metodou Connection.send, které se předává cíl (zde „topic/event“ popř. „topic/event2“), což je jméno tématu s povinným prefixem. Dále se této metodě předá text zprávy a nepovinným parametrem persistent můžeme určit, zda se má zpráva uložit do nastavené databáze či nikoli (tedy zda přežije restart Apache ActiveMQ):
conn.send(destination1, message, persistent='true')
Úplný zdrojový kód zdroje zpráv bude vypadat následovně:
#!/usr/bin/env python import time import stomp destination1 = "/topic/event" destination2 = "/topic/event2" MESSAGES = 10 conn = stomp.Connection(host_and_ports=[("localhost", 61613)]) conn.start() conn.connect(login="admin", passcode="admin") for i in range(0, MESSAGES): message = "Hello world #{i}!".format(i=i) conn.send(destination1, message, persistent='true') conn.send(destination2, message, persistent='true') conn.disconnect()
Konzument (příjemce) zpráv je komplikovanější, než jejich producent. Je to pochopitelné, protože zatímco publikování zprávy spočívá v prostém zavolání metody Connection.send() je příjem zpráv (a čekání na ně) spojen s nějakou formou čekací smyčky, ať již aktivní či pasivní. V knihovně stomp.py můžeme zaregistrovat objekt, jehož metody se budou volat buď při příjmu zprávy nebo v případě, že nastane nějaká chyba. Tyto callback metody (příjem zprávy, informace o chybě) budou zavolány a budou jim předány hlavičky zprávy/chyby a vlastní text zprávy:
def on_message(self, headers, message): print("Received message: {m}".format(m=message)) def on_error(self, headers, message): print("Received an error {e}".format(e=message))
Registrace třídy s těmito metodami vypadá takto:
conn = stomp.Connection(host_and_ports=[("localhost", 61613)]) conn.set_listener('', SimpleListener(conn))
Dále je nutné se přihlásit k odběru zpráv s automatickým potvrzením jejich zpracování:
conn.connect(login="admin", passcode="admin") conn.subscribe(id='simple_listener', destination=destination, ack='auto')
def subscribe(self, destination, id, ack='auto', headers=None, **keyword_headers): def subscribe(self, destination, id=None, ack='auto', headers=None, **keyword_headers):
Úplný zdrojový kód konzumenta zpráv naleznete na adrese https://github.com/tisnik/message-queues-examples/blob/master/amq/example01_publisher_listener/subscriber.py:
#!/usr/bin/env python import time import stomp class SimpleListener: def __init__(self, conn): self.conn = conn def on_message(self, headers, message): print("Received message: {m}".format(m=message)) def on_error(self, headers, message): print("Received an error {e}".format(e=message)) destination = "/topic/event" conn = stomp.Connection(host_and_ports=[("localhost", 61613)]) conn.set_listener('', SimpleListener(conn)) conn.start() conn.connect(login="admin", passcode="admin") conn.subscribe(id='simple_listener', destination=destination, ack='auto') print("Waiting for messages...") while True: time.sleep(10)
Nepatrnou úpravou předchozích dvou skriptů lze zajistit použití komunikační strategie PUSH-PULL, při níž jsou zprávy poslány do fronty a následně (kdykoli později) odeslány klientovi, který se připojí (ovšem jen jedinému klientovi, což je výchozí konfigurace). Úprava spočívá v nahrazení cíle zpráv, kdy se namísto „/topic/event“ použije „/queue/jméno_fronty“.
Následuje ukázka implementace zdroje zpráv posílaných do fronty:
#!/usr/bin/env python import time import stomp destination1 = "/queue/test" destination2 = "/queue/test2" MESSAGES = 10 conn = stomp.Connection(host_and_ports=[("localhost", 61613)]) conn.start() conn.connect(login="admin", passcode="admin") for i in range(0, MESSAGES): message = "Hello world #{i}!".format(i=i) conn.send(destination1, message, persistent='true') conn.send(destination2, message, persistent='true') conn.disconnect()
Skript, který bude zprávy z fronty číst, bude vypadat takto:
#!/usr/bin/env python import time import stomp class SimpleListener: def __init__(self, conn): self.conn = conn def on_message(self, headers, message): print("Received message: {m}".format(m=message)) def on_error(self, headers, message): print("Received an error {e}".format(e=message)) destination = "/queue/test" conn = stomp.Connection(host_and_ports=[("localhost", 61613)]) conn.set_listener('', SimpleListener(conn)) conn.start() conn.connect(login="admin", passcode="admin") conn.subscribe(id='simple_listener', destination=destination, ack='auto') print("Waiting for messages...") while True: time.sleep(10)
V demonstračních příkladech jsme si ukázali zcela základní způsob použití Apache ActiveMQ s využitím protokolu STOMP. V dalších kapitolách se budeme zabývat způsobem sledování (a samozřejmě i ovlivňování) stavu Apache ActiveMQ, k čemuž máme k dispozici hned několik nástrojů.
Základní nástroj pro sledování již známe – je jím příkaz activemq, který nalezneme v adresáři apache-activemq-5.15.8/bin.
Informace o brokerovi zpráv, jednotlivých otevřených „konektorech“ (porty s protokoly) včetně stavu jednotlivých front, získáme příkazem:
$ ./activemq bstat ACTIVEMQ_HOME: /home/tester/apache-activemq-5.15.8 ACTIVEMQ_BASE: /home/tester/apache-activemq-5.15.8 ACTIVEMQ_CONF: /home/tester/apache-activemq-5.15.8/conf ACTIVEMQ_DATA: /home/tester/apache-activemq-5.15.8/data useJmxServiceUrl Found JMS Url: service:jmx:rmi://127.0.0.1/stub/rO0ABXN9AAAAAQAlamF2YXgubWFuYWdlbWVudC5yZW1vdGUucm1pLlJNSVNlcnZlcnhyABdqYXZhLmxhbmcucmVmbGVjdC5Qcm94eeEn2iDMEEPLAgABTAABaHQAJUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uSGFuZGxlcjt4cHNyAC1qYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN0SW52b2NhdGlvbkhhbmRsZXIAAAAAAAAAAgIAAHhyABxqYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN002G0kQxhMx4DAAB4cHc0AAtVbmljYXN0UmVmMgAACTEyNy4wLjAuMQAAiFeZdArPzVDT1a21HUEAAAFoyGEyGYABAHg= Connecting to pid: 9667 BrokerName = localhost TotalEnqueueCount = 1350 TotalDequeueCount = 1090 TotalMessageCount = 21 TotalConsumerCount = 0 Uptime = 3 hours 9 minutes Name = test2 destinationName = test2 destinationType = Queue EnqueueCount = 20 DequeueCount = 0 ConsumerCount = 0 DispatchCount = 0 connectorName = openwire connectorName = stomp Name = test destinationName = test destinationType = Queue EnqueueCount = 21 DequeueCount = 20 ConsumerCount = 0 DispatchCount = 22 Name = event2 destinationName = event2 destinationType = Topic EnqueueCount = 80 DequeueCount = 20 ConsumerCount = 0 DispatchCount = 20 destinationName = ActiveMQ.Advisory.TempQueue_ActiveMQ.Advisory.TempTopic destinationType = Topic connectorName = ws Name = TEST destinationName = TEST destinationType = Queue EnqueueCount = 1010 DequeueCount = 1010 ConsumerCount = 0 DispatchCount = 1010 Name = KahaDBPersistenceAdapter[/home/tester/apache-activemq-5.15.8/data/kahadb,Index:/home/tester/apache-activemq-5.15.8/data/kahadb] connectorName = amqp Name = event destinationName = event destinationType = Topic EnqueueCount = 94 DequeueCount = 40 ConsumerCount = 0 DispatchCount = 40 connectorName = mqtt
Podobně znějící příkaz dstat nám podá přehlednější informace o frontách, jejich velikosti, počtu připojených producentů a konzumentů zpráv, počtu zpráv ve frontách a taktéž informace o paměťových požadavcích jednotlivých front:
$ ./activemq dstat ACTIVEMQ_HOME: /home/tester/apache-activemq-5.15.8 ACTIVEMQ_BASE: /home/tester/apache-activemq-5.15.8 ACTIVEMQ_CONF: /home/tester/apache-activemq-5.15.8/conf ACTIVEMQ_DATA: /home/tester/apache-activemq-5.15.8/data useJmxServiceUrl Found JMS Url: service:jmx:rmi://127.0.0.1/stub/rO0ABXN9AAAAAQAlamF2YXgubWFuYWdlbWVudC5yZW1vdGUucm1pLlJNSVNlcnZlcnhyABdqYXZhLmxhbmcucmVmbGVjdC5Qcm94eeEn2iDMEEPLAgABTAABaHQAJUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uSGFuZGxlcjt4cHNyAC1qYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN0SW52b2NhdGlvbkhhbmRsZXIAAAAAAAAAAgIAAHhyABxqYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN002G0kQxhMx4DAAB4cHc0AAtVbmljYXN0UmVmMgAACTEyNy4wLjAuMQAAiFeZdArPzVDT1a21HUEAAAFoyGEyGYABAHg= Connecting to pid: 9667 Name Queue Size Producer # Consumer # Enqueue # Dequeue # Forward # Memory % ActiveMQ.Advisory.Connection 0 0 0 85 0 0 0 ActiveMQ.Advisory.Consumer.Queue.TEST 0 0 0 4 0 0 0 ActiveMQ.Advisory.Consumer.Queue.test 0 0 0 10 0 0 0 ActiveMQ.Advisory.Consumer.Topic.event 0 0 0 10 0 0 0 ActiveMQ.Advisory.Consumer.Topic.event2 0 0 0 6 0 0 0 ActiveMQ.Advisory.MasterBroker 0 0 0 1 0 0 0 ActiveMQ.Advisory.Producer.Queue.TEST 0 0 0 4 0 0 0 ActiveMQ.Advisory.Queue 0 0 0 3 0 0 0 ActiveMQ.Advisory.Topic 0 0 0 2 0 0 0 TEST 0 0 0 1010 1010 0 0 event 0 0 0 94 40 0 0 event2 0 0 0 80 20 0 0 test 1 0 0 21 20 0 0 test2 20 0 0 20 0 0 0
Ve výchozím nastavení je na adrese http://localhost:8161/admin spuštěno webové rozhraní, do něhož se přihlásíte zadáním jména „admin“ a hesla „admin“:
Obrázek 1: Úvodní stránka webového rozhraní.
Obrázek 2: Základní informace o systému po přihlášení.
Obrázek 3: Informace o frontách.
Obrázek 4: Konzumenti odebírající zprávy z vybrané fronty „TEST“.
Obrázek 5: Přesný text zprávy, která je uložena ve frontě.
Obrázek 6: Přes webové rozhraní je možné zprávu i odeslat.
Systém Apache ActiveMQ naprostou většinu parametrů poskytuje ke čtení (a některé i k modifikaci) přes technologii Java Management Extensions (JMX). Díky tomu je možné ActiveMQ sledovat a konfigurovat z jakékoli aplikace, která dokáže komunikovat přes JMX. Základní aplikací, která je k dispozici v každé instalaci JDK (nikoli však pouze JRE!) je standardní nástroj nazvaný JConsole, který se spouští příkazem jconsole. Podívejme se nyní alespoň ve stručnosti na to, jak lze JConsoli použít společně s ActiveMQ.
Obrázek 7: Po spuštění příkazu jconsole je nutné vybrat proces activemq.jar a popř. potvrdit, že chceme použít nezabezpečené připojení.
Obrázek 8: Na listu nazvaném MBeans vyberte uzel org.apache.activemq a uvidíte všechny atributy poskytované běžícím systémem.
Obrázek 9: Na tomto screenshotu je ukázáno, že po vybrání fronty nazvané „TEST“ je možné volat některé metody ovlivňující její konfiguraci. Další dvě fronty „test“ a „test2“ byly vytvořeny automaticky našimi demonstračními příklady zmíněnými v předchozích kapitolách.
Obrázek 10: Vpravo nahoře jsou vypsány všechny dostupné fronty, přesněji řečeno datové typy, kterými jsou reprezentovány.
Díky tomu, že protokol STOMP je navržen takovým způsobem, aby bylo velmi snadné implementovat nové klienty, a současně se jedná o čistě textový protokol, nebude asi velkým překvapením, že je možné s Apache ActiveMQ komunikovat i s využitím klasického protokolu telnet a stejně pojmenovaného klienta.
Nejprve se připojíme přímo na lokální port číslo 61613, na němž Apache ActiveMQ očekává příkazy předávané přes protokol STOMP:
$ telnet localhost 61613 Trying ::1... Connected to localhost. Escape character is '^]'.
Samotné příkazy vypadají podobně jako hlavičky protokolu HTTP:
Pokud není tento protokol dodržen, bude spojení ukončeno, což je pravděpodobně nejrozumnější cesta, jak se vypořádat se špatně naimplementovanými klienty :-)
Pro navázání připojení použijeme příkaz CONNECT, na dalších řádcích se pak uvede jméno a heslo, prázdný řádek a konečně již zmíněný znak Ctrl+@:
CONNECT login: admin password: admin ^@ CONNECTED server:ActiveMQ/5.15.8 heart-beat:0,0 session:ID:localhost.localdomain-43853-1549550040544-3:40 version:1.0
Dokonce je možné přímo z telnetu poslat i zprávu, a to konkrétně příkazem SEND, jehož parametry jsou cíl zprávy (topic nebo fronta), případné upřesnění příjemců a za prázdným řádkem text zprávy ukončený opět znakem Ctrl+@:
SEND destination:/queue/test receipt: Hello from Telnet! ^@ RECEIPT receipt-id:
Přihlášení k příjmu zpráv z fronty test:
SUBSCRIBE id:0 destination:test ask:client ^@
Přijatá zpráva se zobrazí takto:
MESSAGE content-length:15 expires:0 destination:/queue/test subscription:0 priority:4 message-id:ID:localhost.localdomain-36883-1549643957783-3:15:-1:1:19 persistent:true timestamp:1549653866950 Hello world #9!
Odpojení od Apache ActiveMQ:
DISCONNECT ^@ Connection closed by foreign host.
V této tabulce jsou uvedeny všechny příkazy podporované protokolem STOMP verze 1.2:
Server naopak může posílat tyto rámce (frame):
Příkaz | Stručný popis |
---|---|
SEND | poslání zprávy |
SUBSCRIBE | přihlášení k odběru zpráv |
UNSUBSCRIBE | odhlášení od odběru zpráv |
ACK | potvrzení zprávy |
NACK | negativní potvrzení (vysvětlíme si příště) |
BEGIN | začátek transakce (vysvětlíme si příště) |
COMMIT | commit v transakci (provedení všech operací) |
ABORT | rollback transakce |
DISCONNECT | odpojení klienta |
Příkaz | Stručný popis |
---|---|
MESSAGE | zpráva poslaná serverem |
RECEIPT | potvrzení o zpracování nějakého příkazu serverem |
ERROR | informace o chybě potvrzené serverem |
Kromě Apache ActiveMQ se na samotný závěr jen krátce zmíníme o existenci nástroje nazvaného Red Hat AMQ, který možnosti message brokera dále rozšiřuje. Red Hat AMQ se skládá z několika komponent, přičemž ústředním prvkem je samotný message broker odvozený od AMQ Artemis, ovšem kromě toho nabízí i tzv. Interconnect (viz další kapitolu), možnosti clusteringu, HA, persistenci zpráv, žurnálování, decentralizovaná a redundantní úložiště zpráv atd. Celý systém je možné konfigurovat centrálně, a to buď přes JMX (což jsme si již ukázali výše s nástrojem jconsole) nebo klasicky přes REST API.
Podporovány jsou tyto komunikační strategie:
Systém Red Hat AMQ se skládá z těchto základních komponent, které je možné vzájemně skládat a vytvářet tak systémy s různě komplikovanou architekturou:
V následující tabulce jsou vypsány podporované protokoly jednotlivých součástí Red Hat AMQ (druhá část tabulky obsahuje jednotlivé varianty klientů):
Komponenta | Jazyk | Platforma | Protokol(y) |
---|---|---|---|
AMQ Broker | × | JVM | AMQP 1.0, MQTT, OpenWire, STOMP, Artemis Core Protocol, HornetQ Core Protocol |
AMQ Interconnect | × | Linux | AMQP 1.0 |
AMQ C++ | C++ | Linux, Windows | AMQP 1.0 |
AMQ JavaScript | JavaScript | Node.js, browsery | AMQP 1.0 |
AMQ JMS | Java | JVM | AMQP 1.0 |
AMQ .NET | C# | .NET | AMQP 1.0 |
AMQ Python | Python | Linux | AMQP 1.0 |
AMQ Ruby | Ruby | Linux | AMQP 1.0 |
AMQ Core Protocol JMS | Java | JVM | Core Protocol |
AMQ OpenWire JMS | Java | JVM | OpenWire |
Zdrojové kódy všech dnes popsaných demonstračních příkladů naprogramovaných v Pythonu byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/message-queues-examples (stále na GitHubu :-). V případě, že nebudete chtít klonovat celý repositář (ten je ovšem – alespoň prozatím – velmi malý, dnes má doslova několik kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce.
Příklad | Skript/kód | Popis | Cesta |
---|---|---|---|
1 | publisher.py | zdroj zpráv posílaných se strategií PUB-SUB | https://github.com/tisnik/message-queues-examples/blob/master/amq/example01_publisher_listener/publisher.py |
1 | subscriber.py | příjemce zpráv posílaných se strategií PUB-SUB | https://github.com/tisnik/message-queues-examples/blob/master/amq/example01_publisher_listener/subscriber.py |
2 | publisher.py | zdroj zpráv posílaných se strategií PUSH-PULL | https://github.com/tisnik/message-queues-examples/blob/master/amq/example02_publisher_listener_queue/publisher.py |
2 | subscriber.py | příjemce zpráv posílaných se strategií PUSH-PULL | https://github.com/tisnik/message-queues-examples/blob/master/amq/example02_publisher_listener_queue/subscriber.py |
V této kapitole jsou uvedeny odkazy na všech devět předchozích částí seriálu, v němž se zabýváme různými způsoby implementace front zpráv a k nim přidružených technologií:
Pavel Tišnovský vystudoval VUT FIT a v současné době pracuje ve společnosti Red Hat, kde vyvíjí nástroje pro OpenShift.io.
Internet Info Root.cz (www.root.cz)
Informace nejen ze světa Linuxu. ISSN 1212-8309
Copyright © 1998 – 2019 Internet Info, s.r.o. Všechna práva vyhrazena.