- Опубликовано: 7 мар 2025
- 130
Работа с очередями (Queue) в Laravel 11: руководство для начинающих
Введение
При разработке веб-приложения часто возникают задачи, выполнение которых в рамках одного HTTP-запроса занимает слишком много времени (например, разбор и сохранение большого файла CSV, отправка писем и др.). К счастью, Laravel позволяет легко создавать задания (jobs) и отправлять их в очередь (queue) для асинхронной обработки в фоновом режиме (Очереди Laravel 11.x | Laravel Russian Community). Перемещая трудоемкие операции в очередь, приложение быстрее завершает обработку основного запроса и мгновенно возвращает ответ пользователю, в то время как тяжелая работа выполняется параллельно вне основного потока (Очереди Laravel 11.x | Laravel Russian Community).
В этой статье мы рассмотрим основные понятия системы очередей Laravel (очередь, задание, обработчик), разберемся, зачем они нужны, и покажем, как настроить очереди в Laravel 11 на практике: от выбора драйвера до создания и выполнения jobs, запуска worker-процесса и мониторинга очередей.
Основные понятия очередей Laravel
Очередь (Queue) – механизм для отложенного выполнения задач. Очередь хранит список задач (сообщений) в порядке поступления; каждая задача содержит информацию о том, что и как нужно выполнить (Очереди с Laravel — это просто | OTUS). Laravel предоставляет унифицированный API для работы с разными реализациями очередей – от баз данных до Redis, Beanstalkd или Amazon SQS (Очереди Laravel 11.x | Laravel Russian Community). Вы можете выбрать удобный драйвер очереди и Laravel будет добавлять задачи в соответствующее хранилище (например, таблицу БД или память Redis).
Задание (Job) – отдельная задача, которая должна быть выполнена в фоне. В Laravel задание представлено классом (в пространстве имен App\Jobs
), обычно реализующим интерфейс ShouldQueue
. В коде задания вы описываете конкретную работу, которую нужно выполнить (отправить письмо, обработать изображение, пересчитать статистику и т.д.). Когда задание отправляется в очередь, оно сохраняется в хранилище очереди и ожидает выполнения.
Обработчик очереди (Worker) – фоновый процесс, который постоянно слушает очередь и извлекает новые задания для выполнения. Worker запускается отдельной командой Artisan и работает непрерывно, беря задачи из очереди по одной и выполняя их код. Проще говоря, worker – это “работник”, обслуживающий очередь: он получает задачи из очереди и выполняет соответствующие действия (Очереди с Laravel — это просто | OTUS). Без запущенного worker ваши задания из очереди не будут выполнены, поэтому этот процесс должен работать постоянно (особенно в продакшене).
Зачем использовать очереди?
Главная причина использовать очереди – повышение производительности и отзывчивости приложения. За счёт переноса тяжёлых операций в фон приложения увеличивается скорость работы: пользователь получает ответ практически мгновенно, а ресурсоёмкая логика выполняется асинхронно в фоне (Очереди с Laravel — это просто | OTUS). Например, вместо ожидания 5–10 секунд, пока сервер отправит email при регистрации, пользователь сразу увидит подтверждение, а само письмо отправится чуть позже в фоне. Кроме того, очереди помогают приложению масштабироваться и обрабатывать больше нагрузок. Вы можете запускать несколько worker-процессов параллельно, благодаря чему больше задач будут выполняться одновременно (Очереди с Laravel — это просто | OTUS). Это позволяет обслуживать больше пользователей без увеличения времени отклика – просто добавляя дополнительных рабочих, вы увеличиваете пропускную способность фоновой обработки. Также система очередей обеспечивает надёжность: если выполнение задания завершится неудачно, Laravel отметит его как проваленное, и вы сможете повторить попытку или обработать ошибку отдельно (не влияя на основной пользовательский поток). Итак, очереди решают проблемы длительных операций и делают приложение более быстрым и устойчивым. Теперь перейдём к практике их использования в Laravel 11.
Выбор и настройка драйвера очереди
Laravel поддерживает различные драйверы очередей (провайдеры хранилища), включая sync (синхронное выполнение, без отложенной очереди), database (реляционная БД), Redis, Beanstalkd, Amazon SQS и другие (Очереди Laravel 11.x | Laravel Russian Community). По умолчанию в .env
файле нового приложения Laravel параметр QUEUE_CONNECTION
равен sync
, что означает выполнение задач сразу, без постановки в очередь. Чтобы включить полноценную очередь, необходимо выбрать и настроить подходящий драйвер в конфигурации.
Для начала, в целях простоты, используем драйвер database (базу данных) – он не требует установки дополнительных сервисов. Убедитесь, что у вас настроено подключение к базе данных в Laravel. Далее выполните миграцию для таблицы очереди: Laravel имеет специальную миграцию для хранения заданий. Если такая таблица (jobs
) ещё не создана, сгенерируйте миграцию командой Artisan и примените её:
php artisan queue:table # сгенерировать миграцию для таблицы jobs
php artisan migrate # выполнить миграцию, создаст таблицу jobs
После этого в файле окружения .env
укажите драйвер очереди database:
QUEUE_CONNECTION=database
Теперь Laravel будет сохранять отправленные в очередь задания в таблицу jobs
вашей базы данных. (Для альтернативных драйверов требуются иные настройки: например, для Redis нужно настроить соединение Redis в config/database.php
и установить расширение PHP Redis или пакет predis/predis
(Очереди Laravel 11.x | Laravel Russian Community). В случае SQS или Beanstalkd – добавить соответствующие зависимости Composer (Очереди Laravel 11.x | Laravel Russian Community) и задать креденшлы. Но эти варианты выходят за рамки базового руководства.)
💡 Примечание: При разработке вы можете оставить
QUEUE_CONNECTION=sync
для простоты отладки – задания будут выполняться сразу, как обычный вызов метода. Однако для тестирования реальной очереди (и в продакшене) необходимо переключиться на асинхронный драйвер (например, database или redis) и запустить worker.
Создание и отправка задания (Job) в очередь
После настройки драйвера можно создавать задачи и ставить их в очередь. Предположим, мы хотим отправлять приветственное письмо новому пользователю после регистрации – эту отправку мы сделаем через очередь, чтобы не задерживать процесс регистрации.
1. Создание класса задания. Laravel предоставляет Artisan-команду для генерации класса Job. Выполним в консоли:
php artisan make:job SendWelcomeEmail
Laravel создаст файл с классом задания в директории app/Jobs
. По умолчанию класс будет реализовывать интерфейс ShouldQueue
, а внутри будут заготовлены методы __construct
(конструктор) и handle
(логика выполнения).
Откроем файл app/Jobs/SendWelcomeEmail.php
– он может выглядеть примерно так:
<?php
namespace App\Jobs;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
use App\Mail\WelcomeEmail;
class SendWelcomeEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $user;
public function __construct(User $user)
{
// Получаем модель пользователя, которому будем отправлять письмо
$this->user = $user;
}
public function handle()
{
// Логика отправки письма
Mail::to($this->user->email)
->send(new WelcomeEmail($this->user));
}
}
В этом примере наше задание получает пользователя в конструкторе и в методе handle()
отправляет ему email (через Mailable WelcomeEmail
). Класс WelcomeEmail
(находится в app/Mail
) – это обычный Mailable, который вы могли бы сгенерировать командой php artisan make:mail WelcomeEmail
и настроить шаблон письма. Для простоты деталей Mail опущены, главное здесь – сам факт отправки письма внутри задания.
Обратите внимание на использование интерфейса ShouldQueue
– он сообщает Laravel, что это задание должно выполняться асинхронно через очередь, а не сраз (Очереди Laravel 11.x | Laravel Russian Community)】. Также в классе используются трейт-методы Dispatchable
, Queueable
, InteractsWithQueue
и SerializesModels
– они подключают к классу задания готовую функциональность Laravel (для добавления в очередь, взаимодействия с очередью и серилизации модели пользователя для безопасной передачи через очередь).
2. Отправка задания в очередь. После того как класс задания создан и реализован, его можно поставить в очередь из любого места вашего кода (например, из контроллера, обработчика события или даже из Artisan-команды). В нашем случае, после успешной регистрации нового пользователя, добавим отправку задания SendWelcomeEmail
в очередь. Предположим, у нас есть метод контроллера регистрации пользователя:
// После валидации и создания пользователя...
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
// Помещаем задачу отправки письма в очередь
SendWelcomeEmail::dispatch($user);
Здесь вызывается статический метод dispatch()
у нашего класса задания. Этот метод (предоставляется трейтом Dispatchable
) упаковывает объект задания и отправляет его в настроенную очеред (How To Work With Queues And Jobs In Laravel 11)】. В результате новая запись появится в таблице jobs
(для драйвера database) или в памяти Redis и т.п. – то есть задание сохраняется для последующей обработки. Вы также можете использовать функцию-хелпер dispatch()
или фасад Queue
для отправки, но вызов MyJob::dispatch()
– наиболее читаемый и рекомендуемый способ.
💡 Совет: В методе
dispatch()
можно указывать дополнительные параметры, например очередь или подключение, если вы хотите отправить задание не в очередь по умолчанию. Пример:SendWelcomeEmail::dispatch($user)->onQueue('emails');
отправит задание в именованную очередь `email (Очереди Laravel 11.x | Laravel Russian Community)8】. Однако для простоты у начинающих можно обойтись очередью по умолчанию. После dispatch'а управление сразу возвращается к вашему коду – задание пока не выполнено, оно просто ожидает в очереди. Чтобы его выполнить, необходимо запустить worker.
Запуск обработчика очереди (Worker)
Теперь, когда задание отправлено в очередь, его должен подобрать и выполнить worker. Laravel предоставляет Artisan-команду для запуска воркера:
php artisan queue:work
Эта команда запускает постоянный процесс, который начинает прослушивать очередь и вытаскивать из неё задания для выполнен (Очереди Laravel 11.x | Laravel Russian Community) (Очереди Laravel 11.x | Laravel Russian Community)3】. После запуска queue:work
процесс не завершится автоматически – worker будет работать бесконечно, пока вы не остановите его (Ctrl+C) или не закроете терминал. В ходе работы вы будете видеть в консоли вывод о выполненных задачах (добавьте флаг -v
или --verbose
, чтобы видеть ID заданий в outpu (Очереди Laravel 11.x | Laravel Russian Community)9】.
Для тестирования на локальной машине откройте второй терминал/вкладку: в одном выполняйте обычные запросы (например, php artisan serve
для запуска сервера), а в другом запустите php artisan queue:work
. Теперь при создании нового пользователя ваше задание попадёт в очередь, и запущенный worker сразу же его вытащит и выполнит (отправит письмо).
В production-среде worker должен работать постоянно в фоне. Простого запуска команды в терминале недостаточно, так как при выходе из сессии он остановится. Laravel рекомендует использовать менеджер процессов (Supervisor на Linux) для управления worker'а (Очереди Laravel 11.x | Laravel Russian Community)3】. С помощью Supervisor вы можете настроить автоматический перезапуск воркера при сбоях и запуск нескольких параллельных процессов. Альтернативно, можно воспользоваться пакетом Laravel Horizon (если вы используете драйвер Redis) – Horizon сам управляет процессами воркеров. Выберите подходящий способ, чтобы гарантировать постоянную работу фоновых обработчиков очереди.
Несколько полезных команд для управления очередями через Artisan:
-
php artisan queue:listen
– тоже запускает воркер, но перезапускает фреймворк при каждом задании. Проще использоватьqueue:work
, поэтомуqueue:listen
обычно не применяют. -
php artisan queue:restart
– аккуратно перезапускает все запущенные воркеры (они завершат текущие задания и перезапустятся). Полезно при развёртывании новой версии кода. -
php artisan queue:stop
– останавливает воркер после завершения текущего задания. Можно использовать для контролируемого выключения процесса.
Мониторинг и управление очередью
После настройки очереди и запуска воркера важно уметь отслеживать состояние задач: выполнены ли они успешно, не случилось ли ошибок, сколько задач скопилось в очереди и т.д. Laravel предоставляет несколько средств для мониторинга очередей.
1. Проверка и повтор ошибок. Если какое-то задание завершается с исключением, Laravel пометит его как проваленное и сохранит в специальном хранилище неудачных задач (по умолчанию – таблица failed_jobs
в БД, если вы выполните миграцию для неё командой php artisan queue:failed-table
). Просмотреть список неудачных задач можно командой:
php artisan queue:failed
Каждая запись содержит информацию о классе задания, данных и сообщении об ошибке. Разобрав причину, вы можете повторно запустить провалившееся задание командой php artisan queue:retry <ID_задачи>
или удалить его из списка через `php artisan queue:forget <ID (How To Work With Queues And Jobs In Laravel 11)5】. В логах Laravel (storage/logs) также фиксируются ошибки заданий – не забывайте их проверять при отладке.
2. Laravel Horizon (для Redis). Для продакшена, где требуется удобный мониторинг в реальном времени, существует пакет Laravel Horizon – это красивая панель мониторинга и инструмент управления очередями на базе Red (Очереди Laravel 11.x | Laravel Russian Community)3】. Horizon предоставляет веб-интерфейс, где вы можете видеть текущие задания, завершённые и проваленные задачи, статистику по очередям, время выполнения и т.д. Horizon также упрощает управление воркерами – вы можете настроить число потоков, приоритеты и другие параметры через конфигурацию. Чтобы использовать Horizon, нужно переключиться на драйвер redis
и установить пакет:
composer require laravel/horizon
После установки опубликйте конфигурацию Horizon и запустите его: php artisan horizon
. В браузере по адресу вашего приложения /horizon
откроется dashboard. Все задачи, отправленные в Redis-очередь, будут видны там в режиме реального времени. Подробнее о возможностях Horizon читайте в документации Laravel.
3. Общий мониторинг очереди. Даже без Horizon вы можете оценивать состояние очереди. Например, для драйвера database количество невыполненных заданий – это просто число записей в таблице jobs
. Вы можете настроить периодическое логирование размера очереди или использовать метрики (например, через Prometheus + Grafana) для отслеживания. Если очередь резко растёт – значит воркеры не успевают обрабатывать задачи, стоит увеличить число воркеров или мощности. В Laravel также есть Events для очередей – можно подписаться на события начала и завершения задач, чтобы собирать статистику самостоятельно (но это уже более продвинутые сценарии).
На этом базовое знакомство с очередями Laravel 11 можно завершить. Мы рассмотрели, что такое очереди, задания и воркеры, зачем они нужны и как их настроить. Подводя итог:
- Очереди позволяют выполнять задачи асинхронно, разгружая основное приложение.
- Jobs (задания) – это классы, где описана логика задачи; их можно ставить в очередь для отложенного выполнения.
- Workers – фоновые процессы, обрабатывающие очередь; без них задания не выполнятся. Мы научились настраивать очереди (на примере драйвера базы данных), создавать задания и отправлять их в очередь, запускать воркер для обработки, а также отслеживать выполнение задач и справляться с неудачными заданиями. Использование очередей сделает ваше Laravel-приложение более быстрым, масштабируемым и устойчивым к нагрузкам. Экспериментируйте с этой мощной функцией Laravel и переходите на новые уровни производительности!
Была статья полезной: