Работа с очередями (Queue) в Laravel 11: руководство для начинающих
Эдгар Косулин (обновлено 31 октября 2025) 8 мин чтения
Содержание
Введение
При разработке веб-приложения часто возникают задачи, выполнение которых в рамках одного 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 и переходите на новые уровни производительности!