Очереди с Laravel — это просто
Чтобы работать с очередями в Laravel, достаточно знать и уметь выполнять несколько команд.
1 — Создать обработчик очереди:
$ php artisan make:job ProcessSendingEmail
2 — Отправить новое событие в очередь:
ProcessSendingEmail::dispatch($user);
3 — И запустить обработчик всех событий:
$ php artisan queue:work
Максимально просто, правда?
Давайте теперь рассмотрим немного подробнее наши очереди: что это вообще такое и зачем они нужны. Согласно википедии, очередью (англ. – queue) называется структура данных, из которой удаляется первым тот элемент, который был первым добавлен в очередь. То есть очередь в программировании соответствует «бытовому» понятию очереди. И выглядит очередь примерно так:
Мы добавляем новые объекты в конец очереди, а обрабатываем их с самого начала (принцип FIFO — first in, first out), точно так же, как и с людьми, только со строгим порядком.
Зачем нужны очереди?
В целом они позволяют обеспечить асинхронное выполнение участков программы, что в свою очередь даёт возможность: — увеличить скорость работы приложения — выносим времязатратный и ресурсоемкий код в очередь, и пользователи наслаждаются быстрым ответом от сервера, а все сложные задачи выполняются в фоне; — обслуживать большее количество посетителей — продолжение предыдущего пункта, увеличиваем количество обработчиков — обрабатываем большее количество запросов; — использовать разные языки разработки в одном приложении — да-да, сложные операции можно писать на python, node и даже на С!
Принцип работы
И коротко расскажу вам о принципе работы системы очередей. Она состоит из двух основных компонентов: 1. сервера очередей, 2. обработчика.
Сервер очереди хранит список сообщений (или задач, job queue), которые отправляет ему основное приложение. Задача — это просто информация о том, что и как нужно выполнить.
Обработчик (или worker) — это часть основной программы, которая работает с очередью в обратном направлении. Он получает новые сообщения из очереди и выполняет соответствующие действия.
Пример
Представим себе простую форму регистрации с одним полем для email и кнопкой «Зарегистрироваться». По нажатию на кнопку отправляем данные на сервер и проверяем, есть ли у нас пользователь с таким email в базе или нет, если есть — отправим сообщение на форму, что пользователь уже существует, а если нет — отправим ему на указанную почту email для его подтверждения. Для отправки email у нас есть 2 варианта: 1. отправить синхронно в рамках одного запроса, 2. добавить задачу об отправке email в очередь.
И на самом деле правильного ответа нет, нужно смотреть на конкретную ситуацию. Если у вас небольшой проект, у вас регистрируется несколько человек в час и некритично, если они ждут по 5-10 секунд (а то и все 30) обработки запроса, то первый вариант с синхронной отправкой письма вам подходит. Но в большинстве случаев лучше использовать очередь. Для этого вернемся к началу статьи и выполним пару простых шагов:
1) Создать обработчик очереди:
$ php artisan make:job ProcessSendingEmail
Все обработчики по умолчанию создаются в app/Jobs. Открываем созданный файл app/Jobs/ProcessSendingEmail.php и обновляем функцию handle:
public function handle(User $user) { Mail::send('mail.confirm-registration', [ 'html' => 'Ура! Подтверди свой email по ссылке - https://example.com' ], function ($message) use ($user) { $message->to($user->email)->subject('Подтверждение регистрации’); }); }
Сейчас наш обработчик получает модель пользователя и отсылает ему письмо с помощью стандартного пакета Mail в Laravel, с его возможностями можете ознакомиться в документации.
2) Отправить новое событие в очередь:
ProcessSendingEmail::dispatch($podcast);
public function register(Request $request) { // .... code ProcessSendingEmail::dispatch($user); // .... code }
После вызова функции
3) Запускаем обработчик всех событий в консоли командой:
$ php artisan queue:work
После запуска обработчика все наши события будут поочередно обрабатываться, и если у нас в очереди было 100 писем на отправку, то последнее письмо явно отправится не скоро и будет примерно, как на первой картинке, когда все ждут в очереди. Это примерно так же, когда в магазине толпа людей, а работает только одна касса.
К счастью, нам не нужно платить кассирам и мы можем очень легко решить эту проблему, открыв 100 касс, точнее запустив 100 обработчиков, и наши письма будут отправятся параллельно. Безусловно, надо быть аккуратным с выбором количества обработчиков, ведь каждый будет занимать ресурсы нашего сервера и оптимальное число нужно подбирать из наших возможностей, но помним чем больше обработчиков — тем быстрее все наши сообщения будут обрабатываться.
Итог
В целом использование очередей сильно ускоряет работу вашего приложения и при этом их очень просто использовать, достаточно выполнить 3 простых шага: создать обработчик, вызвать его в нужном месте и запустить воркер. Звучит просто, на практике тоже легко, поэтому не бойтесь использовать их в своем приложении!
Материалы
- https://laravel.com/docs/5.8/queues
- https://laravel.com/docs/5.8/mail
- https://ruhighload.com/Очереди+сообщений
- https://laravel.ru/docs/v5/queues