Что такое Symfony messenger
Прежде чем приступить к изучению этого материала, рекомендую ознакомиться с моим видео о том, что такое очереди сообщений и зачем они нужны. Ссылка на это видео здесь:
https://webkyrs.info/page/zachem-nuzhni-ocheredi-soobschenii-v-programmirovanii-i-chto-eto-takoe
Так вот, symfony messenger - это всего лишь php пакет для composer, который позволяет работать с очередями сообщений на Symfony проще и быстрее.
Эта заметка для того, чтобы у вас появилось вводное представление, что собой представляет этот инструмент.
Более подробнее познакомиться с Symfony messenger можно в этом видеокурсе:
https://webkyrs.info/category/symfony-messenger-rabota-s-ocherediami-soobshchenii
Нужно понимать, что вы можете написать очередь сообщений и самостоятельно, просто с помощью готового пакета настроить все проще и быстрее.
Но, тем не менее, здесь у нас также появляются недостатки в виде того, что получаем ограничения этого пакета и ограничение его возможностями. Мы вынуждены соблюдать правила этого пакета.
В итоге, от использования Symfony messenger мы получаем как плюсы, так и минусы.
Для чего нужен messenger?
Итак, основная задача этого пакета - организовать программную прослойку между брокером сообщений, которым может выступать база данных, Redis, Rabbit MQ и др. и вашим программным кодом.
Задача messenger обеспечить доставку сообщений до брокера сообщений и связать обработку этих сообщений с соответствующим обработчиком.
Таким образом, messenger - это не какая-то конкретная реализация брокера сообщений, а инструментарий для связи программного кода с брокером сообщений.
Установка
Установка здесь достаточно простая. Мы просто устанавливаем дополнительный пакет с помощью пакетного менеджера composer в свой проект
composer require symfony/messenger
После установки нам придется взаимодействовать с рядом составных частей этого пакета, о которых мы сейчас с вами и поговорим.
Что такое Message
В Symfony Messenger Message - это просто PHP-объект, который содержит данные, которые обработчик сообщений будет использовать. Это может быть что угодно, от простого текстового сообщения до сложной структуры данных.
Обычно объекты сообщений несут какие-то данные, но также могут содержать служебную информацию, например, о том, как обрабатывать это сообщение (например, имя сервиса или команды).
Как правило, сообщения создаются в папке src/Message.
Вот пример простого сообщения:
// src/Message/EmailNotification.php namespace App\Message; class EmailNotification { public function __construct( private string $post_id ) { } public function getPostId(): string { return $this->post_id; } }
В этом сообщении мы храним информацию об id той записи, которую нужно обработать.
Добавление сообщения в очередь
Для того, чтобы сообщение попало в очередь, мы с вами должны воспользоваться методом dispatch для специального сервиса MessageBus (это сервис доставки сообщений в очередь).
Предварительно создаем экземпляр класса сообщения и добавляем его в очередь. Выглядеть это может примерно так:
use App\Message\EmailNotification; use Symfony\Component\Messenger\MessageBusInterface; class SomeController { private $messageBus; public function __construct(MessageBusInterface $messageBus) { $this->messageBus = $messageBus; } public function someAction() { // Создаем объект сообщения $message = new EmailNotification('123'); // Отправляем сообщение в очередь $this->messageBus->dispatch($message); // Другие действия... } }
Что такое Message Handler
Для того, чтобы обрабатывать сообщения, которые будут добавляться в очередь, мы с вами должны написать специальный PHP-класс (сервис) в котором будет прописана логика обработки сообщений добавленных в очередь.
Как правило, такие классы создаются в отдельной папке src/MessageHandler.
Выглядеть это может следующим образом:
// src/MessageHandler/EmailNotificationHandler.php namespace App\MessageHandler; use App\Message\EmailNotification; use Symfony\Component\Messenger\Handler\MessageHandlerInterface; class EmailNotificationHandler implements MessageHandlerInterface { public function __invoke(EmailNotification $message) { // Здесь вы можете добавить логику для обработки сообщения // Например, отправка электронной почты $postId = $message->getPostId(); // Логика обработки сообщения... // Например, отправка электронной почты // mail($message->getRecipient(), $message->getSubject(), $message->getContent()); // Пример логирования обработки сообщения // $logger->info('Email notification sent for post with ID ' . $postId); } }
Что такое worker
Но, написанный обработчик сообщений не запустится сам по себе. Чтобы это произошло у нас должна быть запущена и постоянно включена специальная служба, которая будет контролировать поступление сообщений в очередь и как только сообщение поступает в очередь, оно связывается с соответствующим обработчиком и запускается php скрипт, который выполнит действия описанные в message handler.
Если мы говорим про development разработку, эта служба может запускаться командой:
php bin/console messenger:consume async
Эта команда запускает worker, который будет непрерывно получать сообщения из очереди с именем async.
Если мы говорим про production сервер, то там обработка сообщений, как правило, настраивается через службу supervisor, которая следит, чтобы наш worker был постоянно включен.
Что такое транспорт
Транспорт в Symfony Messenger - это механизм, который определяет, как сообщения будут доставлены до обработчиков. Symfony поддерживает различные транспорты, такие как AMQP (RabbitMQ), Redis, Doctrine и др.
В конфигурационных файлах мы с вами прописываем в какой транспорт будет добавляться то или иное сообщение и кто его должен обработать.
Заключение
В общих чертах, мы с вами познакомились с Symfony messenger, но это лишь малая часть из того, что нужно знать, чтобы полноценно начать использовать его в своих проектах.
Более подробно о других особенностях вы можете посмотреть в моем видеокурсе по работе с этим инструментом.
https://webkyrs.info/category/symfony-messenger-rabota-s-ocherediami-soobshchenii
Надеюсь, что после прочтения этой записи общее представление о работе пакета messenger в Symfony у вас появилось.