Hlavní navigace

Apache ActiveMQ – další systém implementující message brokera

Pavel Tišnovský

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.

Doba čtení: 29 minut

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

20. Odkazy na Internetu

1. Apache ActiveMQ – další systém implementující message brokera

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ě).

Poznámka: název ActiveMQ může být poněkud matoucí, protože ještě existuje paralelně vyvíjený systém pojmenovaný ActiveMQ Artemis (odvozený od HornetQ), který (možná) původní ActiveMQ nahradí. Prozatím však k tomu nedošlo, takže dnešní článek je věnován prozatím poslední verzi Active MQ 5.15.8.

2. Protokoly podporované systémem Apache ActiveMQ

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
Poznámka: AUTO není vlastní protokol, protože se jedná o konfigurační volbu, při níž je aktuálně použitý protokol zdetekován automaticky. Pouze první tři protokoly řádky tabulky obsahují skutečně plnohodnotné protokoly určené pro message brokery, ostatní protokoly jsou jen odvozené popř. se jedná o napojení na odlišnou technologii (příkladem je RSS a XMPP).

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 :).

Poznámka: dnešní demonstrační příklady budou založeny na výše zmíněném protokolu STOMP, který sice nemusí být nejrychlejší (je textový a vyžaduje určitý parsing na straně klienta), ovšem jeho použití a odladění celého systému je nejjednodušší.

3. Instalace Apache ActiveMQ

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"
Poznámka: celou URL je skutečně nutné zapsat do uvozovek, aby nebyl znak & interpretován shellem (spuštění příkazu na pozadí).

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>

4. Základní příkazy podporované nástrojem activemq

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

5. Použití nástroje activemq pro poslání popř. pro přijetí zprávy

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

6. Komunikační protokol STOMP a knihovna stomp.py

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

7. Jednoduchý producent zpráv naprogramovaný v Pythonu

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()
Poznámka: samozřejmě by bylo korektnější zajistit zavolání metody Connection.disconnect() i ve chvíli, kdy dojde k nějaké výjimce.

8. Konzument zpráv naprogramovaný taktéž v Pythonu

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')
Poznámka: volání Connection.subscribe se odlišuje podle verze protokolu Stomp:
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/e­xample01_publisher_listener/sub­scriber.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)

9. Využití komunikační strategie PUSH-PULL s frontami zpráv

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)

10. Sledování stavu Apache ActiveMQ z konzole

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
Poznámka: fronty na posledních čtyřech řádcích vznikly po spuštění našich demonstračních příkladů.

11. Webové rozhraní Apache ActiveMQ

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.

Poznámka: dále zmíněný nástroj Red Hat AMQ sice taktéž obsahuje webovou konzoli, ovšem s dalšími možnostmi.

12. Přístup k nastavení a stavu Apache ActiveMQ s využitím nástroje JConsole

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.

13. Ukázka komunikace s Apache ActiveMQ s využitím telnetu přes protokol STOMP

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.

Poznámka: na systému Windows můžete využít například nástroje Tera Term nebo PuTTY.

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:

  1. Na prvním řádku je uvedeno jméno příkazu
  2. Následují případné parametry umístěné na dalších řádcích
  3. Celá hlavička příkazu je ukončena prázdným řádkem, za ní může následovat například text zprávy
  4. Potvrzení příkazu se děje znakem Ctrl+@ (ASCII NUL), který se zapisuje přes Ctrl+Space (nebo zápisem čtyř nul na numerickém bloku s podržením AltGr)

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 :-)

Poznámka: ve výpisech bude tučně označený text zapisovaný uživatelem, zatímco běžným fontem je zapsán výstup, který získáme na terminálu.

14. Připojení a poslání zprávy do fronty

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.

15. Další příkazy podporované protokolem STOMP

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

16. Od Apache ActiveMQ k Red Hat AMQ

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:

  • PUSH-PULL: producer-broker-konzument(i) s jedinou společnou frontou
  • PUSH-PULL: producer-broker-konzument(i) s více frontami pro skupiny konzumentů
  • dtto, ovšem pro strategii PUB-SUB
  • kombinace předchozích možností (typicky PUSH-PULL s „odbočkou“ typu SUB)

17. Součásti (komponenty) systému Red Hat AMQ

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:

  1. AMQ Broker – vlastní message broker, který podporuje větší množství protokolů (viz tabulku níže), persistenci zpráv, samozřejmě podporu front, ale i load balancing, clustering atd. Broker je postavený na projektu ActiveMQ Artemis.
  2. AMQ Interconnect – konfigurovatelná distribuce zpráv, zajišťuje směrování (routing) mezi koncovými uzly (klient, message broker, další služby). Podporuje i tvorbu redundantních cest při směrování, takže je například možné zaručit funkčnost systému i při výpadku některých síťových prvků.
  3. AMQ Console – tato konzole sloužící pro administraci brokerů, směrování zpráv a front, je odlišná od webové konzole, s níž jsme se setkali v předchozích kapitolách.
  4. AMQ Clients – jednotliví (většinou multiplatformní) klienti, kteří jsou taktéž vypsáni v následující tabulce. Rozhraní existují pro Javu (JMS), C++, JavaScript, Python, Ruby, .NET atd.

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

18. Repositář s demonstračními příklady

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/e­xample01_publisher_listener/pu­blisher.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/e­xample01_publisher_listener/sub­scriber.py
       
2 publisher.py zdroj zpráv posílaných se strategií PUSH-PULL https://github.com/tisnik/message-queues-examples/blob/master/amq/e­xample02_publisher_listener_qu­eue/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/e­xample02_publisher_listener_qu­eue/subscriber.py

19. Odkazy na předchozí části seriálu

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í:

  1. Použití nástroje RQ (Redis Queue) pro správu úloh zpracovávaných na pozadí
    https://www.root.cz/clanky/pouziti-nastroje-rq-redis-queue-pro-spravu-uloh-zpracovavanych-na-pozadi/
  2. Celery: systém implementující asynchronní fronty úloh pro Python
    https://www.root.cz/clanky/celery-system-implementujici-asynchronni-fronty-uloh-pro-python/
  3. Celery: systém implementující asynchronní fronty úloh pro Python (dokončení)
    https://www.root.cz/clanky/celery-system-implementujici-asynchronni-fronty-uloh-pro-python-dokonceni/
  4. RabbitMQ: jedna z nejúspěšnějších implementací brokera
    https://www.root.cz/clanky/rabbitmq-jedna-z-nejuspesnejsich-implementaci-brokera/
  5. Pokročilejší operace nabízené systémem RabbitMQ
    https://www.root.cz/clanky/po­krocilejsi-operace-nabizene-systemem-rabbitmq/
  6. ØMQ: knihovna pro asynchronní předávání zpráv
    https://www.root.cz/clanky/0mq-knihovna-pro-asynchronni-predavani-zprav/
  7. Další možnosti poskytované knihovnou ØMQ
    https://www.root.cz/clanky/dalsi-moznosti-poskytovane-knihovnou-mq/
  8. Další možnosti nabízené knihovnou ØMQ, implementace protokolů ØMQ v čisté Javě
    https://www.root.cz/clanky/dalsi-moznosti-nabizene-knihovnou-mq-implementace-protokolu-mq-v-ciste-jave/

20. Odkazy na Internetu

  1. Apache ActiveMQ
    http://activemq.apache.org/
  2. Apache ActiveMQ Artemis
    https://activemq.apache.org/artemis/
  3. Apache ActiveMQ Artemis User Manual
    https://activemq.apache.or­g/artemis/docs/latest/index­.html
  4. Command Line Tools (Apache ActiveMQ)
    https://activemq.apache.org/activemq-command-line-tools-reference.html
  5. stomp.py 4.1.21 na PyPi
    https://pypi.org/project/stomp.py/
  6. Stomp Tutorial
    https://access.redhat.com/do­cumentation/en-US/Fuse_Message_Broker/5.5/html/Con­nectivity_Guide/files/FMBCon­nectivityStompTelnet.html
  7. Apache Camel
    https://camel.apache.org/
  8. Red Hat Fuse
    https://developers.redhat­.com/products/fuse/overvi­ew/
  9. Confusion between ActiveMQ and ActiveMQ-Artemis?
    https://serverfault.com/qu­estions/873533/confusion-between-activemq-and-activemq-artemis
  10. Staré stránky projektu HornetQ
    http://hornetq.jboss.org/
  11. Snapshot JeroMQ verze 0.4.4
    https://oss.sonatype.org/con­tent/repositories/snapshot­s/org/zeromq/jeromq/0.4.4-SNAPSHOT/
  12. Difference between ActiveMQ vs Apache ActiveMQ Artemis
    http://activemq.2283324.n4­.nabble.com/Difference-between-ActiveMQ-vs-Apache-ActiveMQ-Artemis-td4703828.html
  13. Microservices communications. Why you should switch to message queues
    https://dev.to/matteojoli­veau/microservices-communications-why-you-should-switch-to-message-queues–48ia
  14. Stomp.py 4.1.19 documentation
    https://stomppy.readthedoc­s.io/en/stable/
  15. Repositář knihovny JeroMQ
    https://github.com/zeromq/jeromq/
  16. ØMQ – Distributed Messaging
    http://zeromq.org/
  17. ØMQ Community
    http://zeromq.org/community
  18. Get The Software
    http://zeromq.org/intro:get-the-software
  19. PyZMQ Documentation
    https://pyzmq.readthedocs­.io/en/latest/
  20. Module: zmq.decorators
    https://pyzmq.readthedocs­.io/en/latest/api/zmq.deco­rators.html
  21. ZeroMQ is the answer, by Ian Barber
    https://vimeo.com/20605470
  22. ZeroMQ RFC
    https://rfc.zeromq.org/
  23. ZeroMQ and Clojure, a brief introduction
    https://antoniogarrote.wor­dpress.com/2010/09/08/zeromq-and-clojure-a-brief-introduction/
  24. zeromq/czmq
    https://github.com/zeromq/czmq
  25. golang wrapper for CZMQ
    https://github.com/zeromq/goczmq
  26. ZeroMQ version reporting in Python
    http://zguide.zeromq.org/py:version
  27. A Go interface to ZeroMQ version 4
    https://github.com/pebbe/zmq4
  28. Broker vs. Brokerless
    http://zeromq.org/whitepa­pers:brokerless
  29. Learning ØMQ with pyzmq
    https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/
  30. Céčková funkce zmq_ctx_new
    http://api.zeromq.org/4–2:zmq-ctx-new
  31. Céčková funkce zmq_ctx_destroy
    http://api.zeromq.org/4–2:zmq-ctx-destroy
  32. Céčková funkce zmq_bind
    http://api.zeromq.org/4–2:zmq-bind
  33. Céčková funkce zmq_unbind
    http://api.zeromq.org/4–2:zmq-unbind
  34. Céčková C funkce zmq_connect
    http://api.zeromq.org/4–2:zmq-connect
  35. Céčková C funkce zmq_disconnect
    http://api.zeromq.org/4–2:zmq-disconnect
  36. Céčková C funkce zmq_send
    http://api.zeromq.org/4–2:zmq-send
  37. Céčková C funkce zmq_recv
    http://api.zeromq.org/4–2:zmq-recv
  38. Třída Context (Python)
    https://pyzmq.readthedocs­.io/en/latest/api/zmq.html#con­text
  39. Třída Socket (Python)
    https://pyzmq.readthedocs­.io/en/latest/api/zmq.html#soc­ket
  40. Python binding
    http://zeromq.org/bindings:python
  41. Why should I have written ZeroMQ in C, not C++ (part I)
    http://250bpm.com/blog:4
  42. Why should I have written ZeroMQ in C, not C++ (part II)
    http://250bpm.com/blog:8
  43. About Nanomsg
    https://nanomsg.org/
  44. Advanced Message Queuing Protocol
    https://www.amqp.org/
  45. Advanced Message Queuing Protocol na Wikipedii
    https://en.wikipedia.org/wi­ki/Advanced_Message_Queuin­g_Protocol
  46. Dokumentace k příkazu rabbitmqctl
    https://www.rabbitmq.com/rab­bitmqctl.8.html
  47. RabbitMQ
    https://www.rabbitmq.com/
  48. RabbitMQ Tutorials
    https://www.rabbitmq.com/get­started.html
  49. RabbitMQ: Clients and Developer Tools
    https://www.rabbitmq.com/dev­tools.html
  50. RabbitMQ na Wikipedii
    https://en.wikipedia.org/wi­ki/RabbitMQ
  51. Streaming Text Oriented Messaging Protocol
    https://en.wikipedia.org/wi­ki/Streaming_Text_Oriented_Mes­saging_Protocol
  52. Message Queuing Telemetry Transport
    https://en.wikipedia.org/wiki/MQTT
  53. Erlang
    http://www.erlang.org/
  54. pika 0.12.0 na PyPi
    https://pypi.org/project/pika/
  55. Introduction to Pika
    https://pika.readthedocs.i­o/en/stable/
  56. Langohr: An idiomatic Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
    http://clojurerabbitmq.info/
  57. AMQP 0–9–1 Model Explained
    http://www.rabbitmq.com/tutorials/amqp-concepts.html
  58. Part 1: RabbitMQ for beginners – What is RabbitMQ?
    https://www.cloudamqp.com/blog/2015–05–18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html
  59. Downloading and Installing RabbitMQ
    https://www.rabbitmq.com/dow­nload.html
  60. celery na PyPi
    https://pypi.org/project/celery/
  61. Databáze Redis (nejenom) pro vývojáře používající Python
    https://www.root.cz/clanky/databaze-redis-nejenom-pro-vyvojare-pouzivajici-python/
  62. Databáze Redis (nejenom) pro vývojáře používající Python (dokončení)
    https://www.root.cz/clanky/databaze-redis-nejenom-pro-vyvojare-pouzivajici-python-dokonceni/
  63. Redis Queue (RQ)
    https://www.fullstackpython.com/redis-queue-rq.html
  64. Python Celery & RabbitMQ Tutorial
    https://tests4geeks.com/python-celery-rabbitmq-tutorial/
  65. Flower: Real-time Celery web-monitor
    http://docs.celeryproject­.org/en/latest/userguide/mo­nitoring.html#flower-real-time-celery-web-monitor
  66. Asynchronous Tasks With Django and Celery
    https://realpython.com/asynchronous-tasks-with-django-and-celery/
  67. First Steps with Celery
    http://docs.celeryproject­.org/en/latest/getting-started/first-steps-with-celery.html
  68. node-celery
    https://github.com/mher/node-celery
  69. Full Stack Python: web development
    https://www.fullstackpython.com/web-development.html
  70. Introducing RQ
    https://nvie.com/posts/introducing-rq/
  71. Asynchronous Tasks with Flask and Redis Queue
    https://testdriven.io/asynchronous-tasks-with-flask-and-redis-queue
  72. rq-dashboard
    https://github.com/eoranged/rq-dashboard
  73. Stránky projektu Redis
    https://redis.io/
  74. Introduction to Redis
    https://redis.io/topics/introduction
  75. Try Redis
    http://try.redis.io/
  76. Redis tutorial, April 2010 (starší, ale pěkně udělaný)
    https://static.simonwilli­son.net/static/2010/redis-tutorial/
  77. Python Redis
    https://redislabs.com/lp/python-redis/
  78. Redis: key-value databáze v paměti i na disku
    https://www.zdrojak.cz/clanky/redis-key-value-databaze-v-pameti-i-na-disku/
  79. Praktický úvod do Redis (1): vaše distribuovaná NoSQL cache
    http://www.cloudsvet.cz/?p=253
  80. Praktický úvod do Redis (2): transakce
    http://www.cloudsvet.cz/?p=256
  81. Praktický úvod do Redis (3): cluster
    http://www.cloudsvet.cz/?p=258
  82. Connection pool
    https://en.wikipedia.org/wi­ki/Connection_pool
  83. Instant Redis Sentinel Setup
    https://github.com/ServiceStack/redis-config
  84. How to install REDIS in LInux
    https://linuxtechlab.com/how-install-redis-server-linux/
  85. Redis RDB Dump File Format
    https://github.com/sripat­hikrishnan/redis-rdb-tools/wiki/Redis-RDB-Dump-File-Format
  86. Lempel–Ziv–Welch
    https://en.wikipedia.org/wi­ki/Lempel%E2%80%93Ziv%E2%80%93­Welch
  87. Redis Persistence
    https://redis.io/topics/persistence
  88. Redis persistence demystified
    http://oldblog.antirez.com/post/redis-persistence-demystified.html
  89. Redis reliable queues with Lua scripting
    http://oldblog.antirez.com/post/250
  90. Ost (knihovna)
    https://github.com/soveran/ost
  91. NoSQL
    https://en.wikipedia.org/wiki/NoSQL
  92. Shard (database architecture)
    https://en.wikipedia.org/wi­ki/Shard_%28database_archi­tecture%29
  93. What is sharding and why is it important?
    https://stackoverflow.com/qu­estions/992988/what-is-sharding-and-why-is-it-important
  94. What Is Sharding?
    https://btcmanager.com/what-sharding/
  95. Redis clients
    https://redis.io/clients
  96. Category:Lua-scriptable software
    https://en.wikipedia.org/wi­ki/Category:Lua-scriptable_software
  97. Seriál Programovací jazyk Lua
    https://www.root.cz/seria­ly/programovaci-jazyk-lua/
  98. Redis memory usage
    http://nosql.mypopescu.com/pos­t/1010844204/redis-memory-usage
  99. Ukázka konfigurace Redisu pro lokální testování
    https://github.com/tisnik/pre­sentations/blob/master/re­dis/redis.conf
  100. Resque
    https://github.com/resque/resque
  101. Nested transaction
    https://en.wikipedia.org/wi­ki/Nested_transaction
  102. Publish–subscribe pattern
    https://en.wikipedia.org/wi­ki/Publish%E2%80%93subscri­be_pattern
  103. Messaging pattern
    https://en.wikipedia.org/wi­ki/Messaging_pattern
  104. Using pipelining to speedup Redis queries
    https://redis.io/topics/pipelining
  105. Pub/Sub
    https://redis.io/topics/pubsub
  106. ZeroMQ distributed messaging
    http://zeromq.org/
  107. ZeroMQ: Modern & Fast Networking Stack
    https://www.igvita.com/2010/09/03/ze­romq-modern-fast-networking-stack/
  108. Publish/Subscribe paradigm: Why must message classes not know about their subscribers?
    https://stackoverflow.com/qu­estions/2908872/publish-subscribe-paradigm-why-must-message-classes-not-know-about-their-subscr
  109. Python & Redis PUB/SUB
    https://medium.com/@johngrant/python-redis-pub-sub-6e26b483b3f7
  110. Message broker
    https://en.wikipedia.org/wi­ki/Message_broker
  111. RESP Arrays
    https://redis.io/topics/protocol#array-reply
  112. Redis Protocol specification
    https://redis.io/topics/protocol
  113. Redis Pub/Sub: Intro Guide
    https://www.redisgreen.net/blog/pubsub-intro/
  114. Redis Pub/Sub: Howto Guide
    https://www.redisgreen.net/blog/pubsub-howto/
  115. Comparing Publish-Subscribe Messaging and Message Queuing
    https://dzone.com/articles/comparing-publish-subscribe-messaging-and-message
  116. Apache Kafka
    https://kafka.apache.org/
  117. Iron
    http://www.iron.io/mq
  118. kue (založeno na Redisu, určeno pro node.js)
    https://github.com/Automattic/kue
  119. Cloud Pub/Sub
    https://cloud.google.com/pubsub/
  120. Introduction to Redis Streams
    https://redis.io/topics/streams-intro
  121. glob (programming)
    https://en.wikipedia.org/wi­ki/Glob_(programming)
  122. Why and how Pricing Assistant migrated from Celery to RQ – Paris.py
    https://www.slideshare.net/syl­vinus/why-and-how-pricing-assistant-migrated-from-celery-to-rq-parispy-2
  123. Enqueueing internals
    http://python-rq.org/contrib/
  124. queue — A synchronized queue class
    https://docs.python.org/3/li­brary/queue.html
  125. Queues
    http://queues.io/
  126. Windows Subsystem for Linux Documentation
    https://docs.microsoft.com/en-us/windows/wsl/about
  127. RestMQ
    http://restmq.com/
  128. ActiveMQ
    http://activemq.apache.org/
  129. Amazon MQ
    https://aws.amazon.com/amazon-mq/
  130. Amazon Simple Queue Service
    https://aws.amazon.com/sqs/
  131. Celery: Distributed Task Queue
    http://www.celeryproject.org/
  132. Disque, an in-memory, distributed job queue
    https://github.com/antirez/disque
  133. rq-dashboard
    https://github.com/eoranged/rq-dashboard
  134. Projekt RQ na PyPi
    https://pypi.org/project/rq/
  135. rq-dashboard 0.3.12
    https://pypi.org/project/rq-dashboard/
  136. Job queue
    https://en.wikipedia.org/wi­ki/Job_queue
  137. Why we moved from Celery to RQ
    https://frappe.io/blog/technology/why-we-moved-from-celery-to-rq
  138. Running multiple workers using Celery
    https://serverfault.com/qu­estions/655387/running-multiple-workers-using-celery
  139. celery — Distributed processing
    http://docs.celeryproject­.org/en/latest/reference/ce­lery.html
  140. Chains
    https://celery.readthedoc­s.io/en/latest/userguide/can­vas.html#chains
  141. Routing
    http://docs.celeryproject­.org/en/latest/userguide/rou­ting.html#automatic-routing
  142. Celery Distributed Task Queue in Go
    https://github.com/gocelery/gocelery/
  143. Python Decorators
    https://wiki.python.org/mo­in/PythonDecorators
  144. Periodic Tasks
    http://docs.celeryproject­.org/en/latest/userguide/pe­riodic-tasks.html
  145. celery.schedules
    http://docs.celeryproject­.org/en/latest/reference/ce­lery.schedules.html#celery­.schedules.crontab
  146. Pros and cons to use Celery vs. RQ
    https://stackoverflow.com/qu­estions/13440875/pros-and-cons-to-use-celery-vs-rq
  147. Priority queue
    https://en.wikipedia.org/wi­ki/Priority_queue
  148. Jupyter
    https://jupyter.org/
  149. How IPython and Jupyter Notebook work
    https://jupyter.readthedoc­s.io/en/latest/architectu­re/how_jupyter_ipython_wor­k.html
  150. Context Managers
    http://book.pythontips.com/en/la­test/context_managers.html
Našli jste v článku chybu?