Laravel Horizon: worker не запускается - причины и решение ошибок конфигурации
Laravel Horizon - мощный инструмент для управления очередями, но при первом запуске или после изменения конфига он нередко отказывается стартовать. Worker молчит, процессы не появляются, в логах - загадочные сообщения. Эта статья поможет разобраться, почему Horizon не запускает workers, как найти причину и устранить её пошагово. Подойдёт как новичкам, так и тем, кто уже работал с очередями Laravel.
Что такое Laravel Horizon и как он управляет workers
Laravel Horizon - это дашборд и менеджер процессов для очередей на базе Redis. Он запускает и контролирует worker-процессы (php artisan queue:work), следит за нагрузкой и автоматически масштабирует количество воркеров.
Конфигурация Horizon хранится в файле config/horizon.php. Там описываются environments (окружения), supervisors (наборы воркеров) и параметры каждого процесса: очереди, таймауты, количество процессов.
Если что-то настроено неправильно - Horizon стартует, но воркеры не появляются или сразу падают.
Почему Horizon не запускает workers: основные причины
1. Несовпадение окружения (APP_ENV)
Horizon читает конфиг из секции, соответствующей текущему APP_ENV. Если в horizon.php описан только production, а приложение работает в local - воркеры просто не будут запущены.
2. Неверный connection или отсутствие Redis
Horizon работает только с Redis. Если QUEUE_CONNECTION в .env не установлен в redis - воркеры не запустятся.
3. Проблемы с правами и путями PHP
Horizon запускает воркеры как отдельные процессы через php. Если путь к бинарнику PHP не указан или неверный - процессы не стартуют.
4. Ошибки в конфигурационном файле
Опечатки в названиях очередей, неверные типы данных в параметрах (balance, maxProcesses) - всё это приводит к тому, что Horizon молча игнорирует supervisor.
5. Кеш конфигурации не обновлён
После изменения horizon.php забыли сбросить кеш - Horizon продолжает работать по старым настройкам.
Частые ошибки и симптомы
Симптом | Вероятная причина |
|---|---|
Horizon запущен, воркеры не появляются | Несовпадение APP_ENV |
No supervisors are running | Ошибка конфига или пустое окружение |
Connection refused при старте | Redis не запущен или неверный хост |
Воркер стартует и сразу падает | Неверный путь к PHP или нехватка памяти |
Изменения конфига не применяются | Закешированная конфигурация |
Пошаговое решение: как найти и устранить проблему
Шаг 1. Проверьте APP_ENV и секции в horizon.php
php artisan envВывод должен совпадать с ключом окружения в config/horizon.php:
'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto',
'processes' => 10,
'tries' => 3,
],
],
'local' => [ // ← это окружение должно быть, если APP_ENV=local
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'simple',
'processes' => 3,
'tries' => 3,
],
],
],Если секции для вашего окружения нет - добавьте её.
Шаг 2. Убедитесь, что QUEUE_CONNECTION=redis
Откройте .env:
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379Проверьте, что Redis действительно доступен:
redis-cli ping
# Должно вернуть: PONGШаг 3. Сбросьте кеш конфигурации
php artisan config:clear
php artisan horizon:terminate
php artisan horizonНикогда не меняйте horizon.php без последующей очистки кеша.
Шаг 4. Проверьте путь к PHP в конфиге Horizon
В config/horizon.php есть параметр php:
'path' => env('HORIZON_PATH', base_path()),
// и в supervisor:
'php' => PHP_BINARY, // обычно определяется автоматическиЕсли Horizon не находит нужный бинарник - укажите явно:
'supervisor-1' => [
'php' => '/usr/bin/php8.2',
'connection' => 'redis',
// ...
],Шаг 5. Посмотрите логи Horizon
tail -f storage/logs/laravel.logИли через дашборд Horizon (/horizon) → вкладка Failed Jobs. Там будет точная причина падения.
Шаг 6. Проверьте права на запуск
ls -la storage/logs/
ls -la bootstrap/cache/Пользователь, под которым работает Horizon (обычно www-data или текущий пользователь), должен иметь права на запись в storage/ и bootstrap/cache/.
chmod -R 775 storage bootstrap/cacheПримеры реальных ошибок и их решение
Ошибка: No supervisors are running
Horizon запущен, дашборд открывается, но в разделе Supervisors - пусто.
Причина: APP_ENV=staging, а в horizon.php есть только local и production.
Решение: добавить секцию staging в environments или изменить APP_ENV на существующее окружение.
Ошибка: Predis\Connection\ConnectionException: Connection refused
Predis\Connection\ConnectionException: Connection refused [tcp://127.0.0.1:6379]Причина: Redis не запущен.
Решение:
sudo systemctl start redis
sudo systemctl enable redisОшибка: воркер запускается, но сразу завершается
В логах видно:
[2024-01-15 12:00:00] local.ERROR: Allowed memory size of 134217728 bytes exhaustedРешение: увеличьте лимит памяти в конфиге supervisor:
'supervisor-1' => [
'memory' => 256, // мегабайты
// ...
],Часто задаваемые вопросы (FAQ)
Q: Horizon запущен, но очередь не обрабатывается - в чём причина? A: Чаще всего это несовпадение имён очередей. Убедитесь, что в supervisor указана та же очередь (queue), в которую вы отправляете задачи. Например, если задача отправляется в очередь emails, а supervisor слушает default - задача никогда не будет обработана.
Q: Нужно ли перезапускать Horizon после каждого изменения кода? A: Да. Воркеры Horizon кешируют загруженные классы. После деплоя выполните php artisan horizon:terminate - Horizon автоматически перезапустит процессы. В production это делается через Supervisor (системный демон), а не вручную.
Q: Horizon работает локально, но не работает на сервере - почему? A: Типичные причины: разные версии PHP, отсутствие расширения pcntl (требуется для управления процессами), или APP_ENV на сервере указывает на несуществующую секцию конфига.
Q: Как проверить, что Horizon реально запустил воркеры? A: Откройте дашборд /horizon → Supervisors. Там должны отображаться активные процессы. Альтернативно - в терминале:
ps aux | grep queue:work
Q: Можно ли использовать Horizon без Redis? A: Нет. Horizon работает исключительно с Redis. Для других драйверов (database, SQS) используйте php artisan queue:work напрямую.
Q: Как настроить автозапуск Horizon на сервере? A: Через системный Supervisor (не Laravel Horizon supervisor). Пример конфига /etc/supervisor/conf.d/horizon.conf:
[program:horizon]
process_name=%(program_name)s
command=php /var/www/html/artisan horizon
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/horizon.logQ: Что делать, если horizon:terminate не останавливает процессы? A: Найдите PID вручную и завершите:
ps aux | grep artisan
kill -9 <PID>Q: Horizon пишет This application is not using the redis queue driver - как исправить? A: В .env измените QUEUE_CONNECTION=redis и выполните php artisan config:clear.
Полезные советы и лучшие практики
Всегда используйте системный Supervisor для автозапуска Horizon в production. Это гарантирует, что процесс поднимется после перезагрузки сервера.
Разделяйте очереди по приоритету. Создавайте отдельные supervisors для критичных задач (payments) и фоновых (notifications).
Мониторьте метрики. Дашборд Horizon показывает throughput и время выполнения - используйте это для оптимизации количества процессов.
Не храните большие объекты в задачах. Передавайте только ID, а данные получайте внутри задачи - это снижает нагрузку на Redis.
Настройте оповещения. Horizon поддерживает уведомления о длинных очередях через Horizon::routeMailNotificationsTo() и Slack.
Проверяйте версию Horizon после обновления Laravel - мажорные версии фреймворка иногда требуют обновления Horizon.
composer show laravel/horizon | grep versions
Итог
Большинство проблем с запуском workers в Laravel Horizon сводится к трём вещам: несовпадение окружения, неверная конфигурация Redis и устаревший кеш. Прежде чем копать глубже - проверьте APP_ENV, убедитесь что Redis отвечает на PONG, и сбросьте кеш конфигурации. Затем смотрите логи - там всегда есть ответ.
Комментарии
Чтобы оставить комментарий, войдите в аккаунт.