Ваш сайт на Yii2 иногда подтормаживает? Пользователи жалуются на долгую отправку писем или генерацию отчётов? Скорее всего, вы выполняете тяжёлые задачи прямо в запросе. Очереди — это способ разгрузить приложение и сделать его отзывчивым. В статье разберём, как подружить Yii2 с очередями задач, какие драйверы выбрать и как не наступить на грабли.
Что такое очередь задач и зачем она нужна
Очередь задач — это как список дел, которые нужно сделать потом. Вы кладёте задачу в очередь и сразу отвечаете пользователю «всё ок», а обработчик берёт задачу и выполняет её в фоне. В Yii2 для этого есть встроенный компонент queue, который поддерживает разные хранилища: от простого файла до Redis и RabbitMQ.
Зачем это нужно? Представьте, что пользователь регистрируется. Вы отправляете приветственное письмо, генерируете PDF-счёт и делаете запись в аудит. Если делать это синхронно, страница будет грузиться секунды. С очередью — миллисекунды. Пользователь доволен, сервер не перегружен.
Устанавливаем и настраиваем очередь в Yii2
Для начала установим пакет через Composer:
composer require yiisoft/yii2-queue
Теперь настроим компонент в конфиге приложения. Самый простой драйвер — файловый (подходит для разработки). В продакшене лучше использовать Redis или AMQP.
// config/console.php или config/web.php
return [
'components' => [
'queue' => [
'class' => \yii\queue\drivers\File::class,
'path' => '@runtime/queue',
],
],
];
После настройки нужно запустить обработчик. В консоли выполняем:
yii queue/listen
Эта команда будет слушать очередь и выполнять задачи по мере поступления. Для продакшена лучше использовать супервизор (например, systemd или supervisor), чтобы процесс перезапускался при падении.
Как создавать и отправлять задачи в очередь
Задача — это обычный класс, реализующий интерфейс \yii\queue\JobInterface. Внутри метода execute() вы пишете логику. Вот пример задачи для отправки письма:
namespace app\jobs;
use yii\base\BaseObject;
use yii\queue\JobInterface;
class SendEmailJob extends BaseObject implements JobInterface
{
public $to;
public $subject;
public $body;
public function execute($queue)
{
// Логика отправки письма
Yii::$app->mailer->compose()
->setTo($this->to)
->setSubject($this->subject)
->setTextBody($this->body)
->send();
}
}
Чтобы добавить задачу в очередь, используем компонент queue:
Yii::$app->queue->push(new SendEmailJob([
'to' => 'user@example.com',
'subject' => 'Добро пожаловать!',
'body' => 'Спасибо за регистрацию.',
]));
Можно отложить выполнение на определённое время:
Yii::$app->queue->delay(300)->push(new SendEmailJob([...]));
Это выполнит задачу через 5 минут (300 секунд). Удобно для напоминаний.
Обработка ошибок и повторные попытки
Задачи могут падать: сеть отвалилась, внешний API вернул ошибку. Yii2 по умолчанию пытается выполнить задачу один раз. Но можно настроить повторные попытки. Для этого в задаче реализуем метод getTtr() (time to reserve) и переопределим поведение при ошибке.
Проще всего использовать встроенный механизм повторных попыток через настройку компонента очереди:
'queue' => [
'class' => \yii\queue\drivers\Redis::class,
'attempts' => 3, // количество попыток
'ttr' => 300, // время на выполнение в секундах
],
Если задача падает с исключением, она будет повторена до трёх раз. После этого попадёт в список неудачных (если драйвер поддерживает). Посмотреть неудачные задачи можно командой:
yii queue/info
А перезапустить все неудачные:
yii queue/retry
Yii::error() или пишите в отдельный лог-файл. Иначе отладка превратится в квест.
Сравнение драйверов очередей для Yii2
Выбор драйвера зависит от нагрузки и инфраструктуры. Вот таблица с популярными вариантами:
| Драйвер | Когда использовать | Плюсы | Минусы |
|---|---|---|---|
| File | Разработка, малые проекты | Простота, без доп. софта | Не для высокой нагрузки, нет конкурентного доступа |
| Redis | Средние и крупные проекты | Быстрота, надёжность, поддержка задержек | Нужен Redis-сервер |
| RabbitMQ (AMQP) | Высокие нагрузки, сложные сценарии | Гарантированная доставка, гибкая маршрутизация | Сложнее в настройке |
| Database | Небольшие проекты с уже готовой БД | Не нужен отдельный сервер | Медленнее, нагрузка на БД |
Для большинства проектов на Yii2 оптимален Redis. Он быстрый, простой в установке и хорошо документирован. Если у вас уже есть RabbitMQ — используйте его.
Практические советы и подводные камни
- Идемпотентность. Задача может выполниться дважды (например, при повторной попытке). Убедитесь, что повторное выполнение не навредит. Например, отправка письма дважды — плохо. Добавьте проверку: «если письмо уже отправлено, пропустить».
- Таймауты. Устанавливайте разумное время выполнения (ttr). Если задача висит дольше, она будет прервана и возвращена в очередь. Это лучше, чем вечно висящий процесс.
- Мониторинг. Следите за длиной очереди. Если она растёт — значит, обработчики не справляются. Добавьте больше воркеров или оптимизируйте задачи.
- Логирование. Пишите в лог начало и конец выполнения задачи. Это поможет при отладке.
Что в итоге
Очереди задач в Yii2 — это мощный инструмент, который делает приложение быстрее и надёжнее. Настройка занимает немного времени: установить пакет, сконфигурировать компонент, написать класс задачи и запустить воркер. Главное — не забывать про идемпотентность, таймауты и мониторинг. Тогда очередь станет вашим верным помощником, а не источником головной боли.
Начните с простого драйвера File, поэкспериментируйте, а когда проект вырастет — переходите на Redis или RabbitMQ. Удачи в разработке!



