Kolejki w Pimcore z Symfony Messenger wdraża się dziś prościej niż kiedykolwiek. Pokazujemy, jak skrócić czas odpowiedzi aplikacji i przekazać czasochłonne zadania do wyspecjalizowanych usług.
Spis treści 6 rozdziałów
Mniej czekania: Symfony Messenger wykona zadanie aplikacji Pimcore w tle.
Czym jest Symfony Messenger?
Symfony Messenger pomaga aplikacjom zarządzać kolejkami, zwłaszcza gdy komunikują się z innymi systemami albo przekazują zadania innym usługom. Pimcore zastąpił nim wszystkie wcześniejsze kolejki asynchroniczne, dlatego integracja Symfony Messenger z projektem jest dziś znacznie prostsza.
Przykład z praktyki
Załóżmy, że na stronie jest formularz zgłoszenia do konkursu, nawet bardzo prosty, z trzema polami:
- imię
- wiadomość

Jest on też bardzo podobny do definicji klasy obiektów, które będą przechowywane w Pimcore.

Kontroler obsługuje formularz, zapisuje obiekt w bazie danych i wysyła odpowiedni e-mail.
To rzeczywiście działa, ale czy da się to zrobić lepiej?
Na czym polega problem?
Przed wprowadzeniem Symfony Messenger obsługa formularza, zapis obiektu i wysyłka e-maila trwały około 4 sekund.

Dlaczego? Głównym powodem jest komunikacja z serwerem SMTP, który wysyła wiadomości. Gdy pominąć ten krok i tylko zapisać obiekt, czas przetwarzania jest zupełnie inny. Ta różnica wpływa na to, jak użytkownicy oceniają wygodę i szybkość strony.

Magia kolejek
Właśnie dlatego powstał Symfony Messenger, a Pimcore zastąpił nim stare kolejki asynchroniczne. Potrzebne są dwie klasy:
- CompetitionApplicationMessage, która przechowuje dane; w tym przykładzie jest to CompetitionApplication.
- CompetitionApplicationMessageHandler, która w tym przykładzie odpowiada za zapis obiektu i wysyłkę e-maila.
Teraz w kontrolerze, zamiast zapisywać obiekt i wysyłać e-mail, wywołujemy CompetitionApplicationMessage, wstrzykując MessageBusInterface do metody, która odbiera żądania. Trzeba pamiętać o przełączeniu usług. W konfiguracji yaml oznaczamy handler jako message handler.
Wygląda obiecująco. Formularz nadal jednak przetwarza się prawie 4 sekundy, co jest dużym rozczarowaniem.
Kluczem jest asynchroniczność.
Symfony Messenger wykonuje zadania automatycznie. Aby działały asynchronicznie, trzeba przygotować plik konfiguracyjny config/packages/messenger.yaml z definicją, jak wiadomość ma być wykonana i obsłużona. Zmienna środowiskowa MESSENGER_TRANSPORT_DSN wskazuje transport odpowiedzialny za kolejki. Może to być Redis, RabbitMQ, a nawet baza danych. Aby zadania z kolejki wykonywały się poprawnie i cyklicznie przez cron albo supervisord, należy uruchomić polecenie php bin/console messenger:consume async.
Efekty
Asynchroniczna obsługa formularza przez Symfony Messenger daje wyraźny wzrost wydajności.

Gdy procesami steruje narzędzie takie jak supervisord, logika zadania obciąża usługę odpowiedzialną za procesy, a nie aplikację. Przy dużym ruchu i wielu procesach daje to dużą poprawę odczuwalnej wydajności i stabilności.
Jest też inna korzyść. Gdy usługa SMTP nie działa, zadanie nie zostanie uznane za zakończone, a system spróbuje je wykonać jeszcze trzy razy. Gdyby logika została w kontrolerze, a e-mail nie zostałby wysłany, ponownej próby nie byłoby wcale. Liczbę prób i odstępy między nimi ustawia się w konfiguracji Messengera.




