Что такое jobs, events и listeners в Laravel?
Jobs — единицы фоновой работы, отправляемые в очередь. Events — широковещательные уведомления о произошедшем. Listeners — обработчики конкретного события, могут реализовывать ShouldQueue для асинхронного выполнения.
Jobs (Задания)
Job — класс, инкапсулирующий одну единицу работы, которая выполняется синхронно или асинхронно через очередь. Создаётся командой php artisan make:job ProcessPayment.
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessPayment implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $timeout = 60;
public function __construct(
private readonly Order $order,
private readonly string $paymentToken,
) {}
public function handle(PaymentGateway $gateway): void
{
$gateway->charge($this->order, $this->paymentToken);
}
public function failed(\Throwable $e): void
{
// уведомить владельца заказа
$this->order->user->notify(new PaymentFailed($e->getMessage()));
}
}
// Отправка в очередь
ProcessPayment::dispatch($order, $token);
// С задержкой 5 минут
ProcessPayment::dispatch($order, $token)->delay(now()->addMinutes(5));
// Синхронно (без очереди)
ProcessPayment::dispatchSync($order, $token);
Events (События)
Event — простой класс-DTO, сигнализирующий о том, что что-то произошло в системе. Создаётся через php artisan make:event OrderPlaced. Событие само по себе ничего не делает — оно только несёт данные.
<?php
namespace App\Events;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class OrderPlaced
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(
public readonly Order $order,
) {}
}
// Диспетчеризация события
OrderPlaced::dispatch($order);
// или через хелпер
event(new OrderPlaced($order));
Listeners (Слушатели)
Listener — класс, реагирующий на конкретное событие. Создаётся через php artisan make:listener SendOrderConfirmation --event=OrderPlaced. Регистрируется в EventServiceProvider (Laravel 10) или через атрибут #[ListenTo] (Laravel 11+).
<?php
// Регистрация в App\Providers\EventServiceProvider
protected $listen = [
OrderPlaced::class => [
SendOrderConfirmation::class,
UpdateInventory::class,
NotifyWarehouse::class,
],
];
// Сам listener
class SendOrderConfirmation implements ShouldQueue
{
public string $queue = 'notifications';
public function handle(OrderPlaced $event): void
{
Mail::to($event->order->user)
->send(new OrderConfirmationMail($event->order));
}
}
Когда что использовать
- Job — изолированная фоновая задача с чёткой ответственностью: отправить email, обработать файл, вызвать внешний API. Один job = одна задача.
- Event + Listeners — когда одно действие должно вызвать несколько независимых реакций (отправить письмо, обновить аналитику, уведомить Slack). Decoupling через события упрощает добавление новых реакций.
- Listeners тоже реализуют
ShouldQueueи выполняются асинхронно — это делает их функционально схожими с jobs, но с семантикой «реакция на событие».
Подводные камни
- Сериализация Eloquent-моделей — трейт
SerializesModelsсохраняет только primary key и перезагружает модель при выполнении. Если модель удалена к тому моменту — job упадёт сModelNotFoundException. Проверяйте существование вhandle(). - Listeners без ShouldQueue блокируют запрос — если слушатель выполняет медленную операцию синхронно, время ответа HTTP-запроса увеличивается на всё это время.
- Порядок listeners не гарантирован при параллельных воркерах — если несколько listeners одного события попадают в очередь, они могут выполниться в любом порядке.
- Дублирование при failed job retry — job, упавший после частичного выполнения (например, деньги списаны, но письмо не отправлено), при повторном запуске может задублировать операцию. Используйте идемпотентность через уникальный ключ или проверку статуса.
- Job chaining прерывается при ошибке —
Bus::chain([...])->dispatch()останавливается на первом упавшем job, последующие не выполняются.
Common mistakes
- Сводить jobs events listeners к названию метода без lifecycle и failure path.
- Игнорировать модель runtime: Laravel 13 поверх PHP: request проходит через HTTP kernel, middleware, routing, controller/action и response pipeline.
- Не отделять validation, authorization, transaction boundary и business logic.
- Не обсуждать idempotency, retries, shutdown и observability.
What the interviewer is testing
- Объясняет jobs events listeners через конкретную точку lifecycle в Laravel.
- Приводит корректный минимальный пример без вымышленных методов или callbacks.
- Называет edge cases: пустые значения, ошибки, транзакции, безопасность или concurrency.
- Связывает решение с метриками, backpressure, retry policy и graceful shutdown.