Praktický návod
Jak zpracovávat úlohy na pozadí pomocí RabbitMQ
E-mail, import nebo generování souboru nemusí zdržovat návštěvníka. Předáš práci na pozadí a aplikace může hned odpovědět.
Nejdřív stručně
K čemu je RabbitMQ?
RabbitMQ pomáhá předat práci mezi částmi aplikace. Jedna část vytvoří zprávu a uloží ji do fronty zpráv. Druhá ji později vezme a zpracuje.
Odesílatel zprávy se často označuje jako producer. Zpracovatel je consumer. Důležité je, že web nemusí čekat na pomalou práci.
Připrav si
Co potřebuješ předem
Než začneš, vyber jednu malou úlohu. Třeba odeslání potvrzovacího e-mailu.
- RabbitMQ spuštěné lokálně nebo jako spravovanou službu.
- Místo v aplikaci, kde vznikne úloha. Například po vytvoření objednávky.
- Samostatný proces pro consumera. Musí běžet i po zavření prohlížeče.
- Jasný způsob, jak poznáš úspěch i chybu. Stačí log a jednoduchý test na začátku.
Krok 1
Rozděl práci na zprávu a zpracování
Začni co nejmenší změnou. Nech web vytvořit zprávu a náročnou práci přesuň do consumera.
1. Vyber jednu pomalou úlohu
- Nejprve si vezmi práci, která nemusí skončit před odpovědí uživateli. Dobrá volba je e-mail nebo vytvoření náhledu obrázku.
- Nedávej do zprávy celé objednávky ani citlivá data. Většinou stačí ID záznamu a typ práce.
- Consumer si podle ID načte aktuální data z aplikace.
2. Pošli zprávu až po uložení dat
- Nejdřív bezpečně ulož změnu do databáze. Teprve potom vytvoř zprávu pro frontu.
- Zpráva má říkat jen to, co má consumer udělat. Třeba „odeslat e-mail k objednávce 123“.
- Počítej s tím, že zpráva může přijít víckrát. Consumer proto nesmí stejnou věc provést dvakrát bez kontroly.
3. Spusť consumera
- Consumer běží mimo webový požadavek a čeká na další zprávu.
- V Symfony Messengeru se obvykle spouští příkazem níže. Název transportu async si uprav podle své konfigurace.
- Na serveru ho spouštěj přes správce procesů. Lokálně ho nech běžet v samostatném terminálu.
php bin/console messenger:consume async -vv Krok 2
Ověř, že práce opravdu běží na pozadí
Nezůstávej jen u toho, že stránka nehlásí chybu. Ověř celou cestu zprávy.
-
Vytvoř jednu bezpečnou testovací úlohu
Spusť akci, která zprávu odešle. V odpovědi webu by nemělo být čekání na vlastní zpracování.
-
Sleduj consumera
V jeho výstupu nebo logu ověř, že zprávu převzal a dokončil. Když ji nevidí, hledej problém mezi producerem a frontou.
php bin/console messenger:consume async -vv -
Zkontroluj výsledek
Ověř konkrétní dopad: odeslaný e-mail, vytvořený soubor nebo změněný záznam. Tím víš, že consumer neudělal jen polovinu práce.
Když to zlobí
Nejčastější chyby
Zprávy ve frontě přibývají, ale nic se neděje
Consumer nejspíš neběží, spadl nebo poslouchá jinou frontu. Nejprve zkontroluj jeho log a název transportu v konfiguraci.
Úloha se spustí dvakrát
Doručení zprávy může být opakované. Do zpracování přidej kontrolu, zda už byla práce dokončena. Pomůže princip idempotence.
Consumer padá na jedné chybné zprávě
Zapiš chybu, nastav rozumné opakování a problémovou zprávu odděl od běžných. Neopakuj ji donekonečna; pro další pokus se hodí pravidla pro retry.
Web pořád čeká stejně dlouho jako dřív
Zkontroluj, zda těžkou práci opravdu neděláš ještě před odesláním zprávy. Web má vytvořit zprávu a vrátit odpověď, ne poslat e-mail sám.
Hotovo
První úloha už nemusí brzdit web.
RabbitMQ teď může převzít pomalou práci. Přidávej další úlohy postupně a u každé nejdřív ověř celý průchod.