Laravel Horizon
11.x
.
Почему это важно?
Вступление
Прежде чем углубляться в Laravel Horizon, вам следует ознакомиться с базовыми службами очередей Laravel. Horizon дополняет очередь Laravel дополнительными функциями, которые могут сбивать с толку, если вы еще не знакомы с основными функциями, предлагаемыми Laravel.
Laravel Horizon предоставляет красивую панель управления и конфигурацию для ваших очередей Redis, работающих на Laravel. Horizon позволяет легко отслеживать ключевые показатели системы очередей, такие как пропускная способность, время выполнения и сбои заданий.
При использовании Horizon вся ваша конфигурация обработчика очереди хранится в одном простом файле конфигурации. Определив конфигурацию воркеров (worker) приложения в файле с контролем версий, вы можете легко масштабировать или изменять воркеры очереди приложения при развертывании.
Установка
Laravel Horizon требует, чтобы вы использовали Redis для управления очередью. Следовательно, вы должны убедиться, что соединение с очередью настроено на
redis
в файле конфигурации приложенияconfig/queue.php
.
Вы можете установить Horizon в свой проект с помощью диспетчера пакетов Composer:
composer require laravel/horizon
После установки Horizon опубликуйте его ресурсы с помощью Artisan-команды horizon:install
:
php artisan horizon:install
Настройка
После публикации ресурсов Horizon его основной файл конфигурации будет расположен по адресу config/horizon.php
. Этот файл конфигурации позволяет вам настроить параметры обработчика очереди для приложения. Каждый вариант конфигурации включает описание своего назначения, поэтому обязательно внимательно изучите этот файл.
Horizon использует Redis-соединение с именем «horizon». Это имя соединения Redis зарезервировано и не должно назначаться другому Redis-соединению в файле конфигурации
database.php
или в качестве значения параметраuse
в файле конфигурацииhorizon.php
.
Окружение
Основным параметром конфигурации Horizon, с которым вы должны ознакомиться после установки, является параметр конфигурации environments
. Этот параметр конфигурации представляет собой массив сред, в которых работает ваше приложение, и определяет параметры рабочего процесса для каждой среды. По умолчанию эта запись содержит окружение production
и local
. Однако вы можете добавлять дополнительные среды по мере необходимости:
'environments' => [
'production' => [
'supervisor-1' => [
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],
'local' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],
Когда вы запускаете Horizon, он будет использовать параметры конфигурации рабочего процесса для среды, в которой работает ваше приложение. Как правило, среда определяется значением APP_ENV
переменной среды. Например, стандартная локальная среда Horizon настроена на запуск трех рабочих процессов и автоматическое выравнивание количества рабочих процессов, назначенных каждой очереди. По умолчанию рабочая среда настроена на запуск максимум 10 рабочих процессов и автоматический баланс количества рабочих процессов, назначенных каждой очереди.
Вы должны убедиться, что раздел
environment
файла конфигурацииhorizon
содержит запись для каждой среды, в которой вы планируете запускать Horizon.
Supervisors (Наблюдатели)
Как вы можете увидеть в файле конфигурации Horizon по умолчанию — каждая среда может содержать один или несколько “supervisors” (наблюдателей). По умолчанию в файле конфигурации этот supervisor определяется как supervisor-1
; однако вы можете называть своих supervisors как хотите. Каждый supervisor, по сути, отвечает за “наблюдение” за группой рабочих процессов и заботится о балансировке рабочих процессов по очередям.
Вы можете добавить дополнительных “supervisors” в данную среду, если хотите определить новую группу рабочих процессов, которые должны выполняться в этой среде. Вы можете сделать это, если хотите определить другую стратегию балансировки или количество рабочих процессов для данной очереди, используемой вашим приложением.
Значения по умолчанию
В файле конфигурации Horizon по умолчанию вы заметите параметр конфигурации defaults
. Эта опция конфигурации определяет значения по умолчанию для Supervisors приложения. Значения конфигурации супервизора по умолчанию будут объединены с конфигурацией супервизора для каждой среды, что позволит вам избежать ненужного повторения при определении супервизоров.
Стратегии балансировки
В отличие от стандартной системы очередей Laravel, Horizon позволяет вам выбирать из трех стратегий балансировки рабочих процессов (worker): simple
, auto
и false
. Стратегия simple
, которая используется в конфигурационном файле по умолчанию, равномерно распределяет входящие задания между рабочими процессами:
'balance' => 'simple',
Стратегия auto
регулирует количество рабочих процессов в очереди на основе текущей рабочей нагрузки очереди. Например, если ваша очередь notifications
имеет 1000 ожидающих заданий, а ваша очередь render
пуста, Horizon будет выделять больше воркеров в очередь notifications
, пока она не станет пустой.
При использовании стратегии auto
вы можете определить параметры конфигурации minProcesses
и maxProcesses
для управления минимальным и максимальным количеством рабочих процессов, которые Horizon должен масштабировать в большую или меньшую стороны:
'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto',
'minProcesses' => 1,
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
'tries' => 3,
],
],
],
Значения конфигурации balanceMaxShift
и balanceCooldown
определяют, насколько быстро Horizon будет масштабироваться в соответствии с требованиями рабочих процессов. В приведенном выше примере каждые три секунды будет создаваться или уничтожаться максимум один новый процесс. Вы можете изменять эти значения по мере необходимости в зависимости от потребностей вашего приложения.
Когда для параметра balance
установлено значение false
, будет использоваться поведение Laravel по умолчанию, обрабатывающее очереди в том порядке, в котором они перечислены в конфигурации.
Авторизация в информационной панели (dashboard)
Horizon предоставляет информационную панель (dashboard) по URI /horizon
. По умолчанию вы сможете получить доступ к этой панели инструментов только в локальной среде. Однако в файле app/Providers/HorizonServiceProvider.php
есть определение шлюза авторизации. Этот шлюз контролирует доступ к Horizon во внешних средах. Вы можете настроить этот шлюз по мере необходимости, чтобы ограничить доступ к вашему приложению Horizon:
/**
* Регистрация шлюза Horizon.
*
* Этот шлюз определяют, кто может получить доступ к Horizon во внешней среде.
*
* @return void
*/
protected function gate()
{
Gate::define('viewHorizon', function ($user) {
return in_array($user->email, [
'taylor@laravel.com',
]);
});
}
Альтернативные стратегии аутентификации
Помните, что Laravel автоматически добавляет к шлюзу аутентифицированного пользователя замыкание (closure). Если ваше приложение обеспечивает безопасность Horizon с помощью другого метода, например ограничения IP-адресов, то пользователям Horizon может и не требоваться “аутентификация”. Следовательно, нужно будет изменить написание функции (сигнатуру) выше с function ($user)
на function ($user = null)
, чтобы Laravel не требовал аутентификации.
Обновление Horizon
При обновлении до новой версии Horizon важно внимательно изучить руководство по обновлению. Кроме того, при обновлении до любой новой версии Horizon вам следует повторно опубликовать ресурсы Horizon:
php artisan horizon:publish
Чтобы поддерживать ресурсы в актуальном состоянии и избежать проблем в будущих обновлениях, вы можете добавить команду horizon: publish
к сценариям post-update-cmd
в файле composer.json
вашего приложения:
{
"scripts": {
"post-update-cmd": [
"@php artisan horizon:publish --ansi"
]
}
}
Запуск Horizon
После того как вы настроили свои супервизоры (supervisors) и рабочие процессы (workers) в файле конфигурации приложения config/horizon.php
, вы можете запустить Horizon, используя Artisan-команду horizon
. Эта единственная команда запустит все настроенные рабочие процессы для текущей среды:
php artisan horizon
Вы можете приостановить процесс Horizon и дать ему указание продолжить обработку заданий, используя Artisan-команды horizon:pause
и horizon:continue
:
php artisan horizon:pause
php artisan horizon:continue
Вы также можете приостановить и продолжить определенные Horizon супервизоры, используя Artisan-команды horizon:pause-supervisor
и horizon:continue-supervisor
:
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1
Вы можете проверить текущий статус процесса Horizon, используя Artisan-команду horizon:status
:
php artisan horizon:status
Вы можете корректно завершить процесс Horizon, используя Artisan-команду horizon:terminate
. Все задания, которые в настоящее время обрабатываются, будут завершены, а затем Horizon прекратит работу:
php artisan horizon:terminate
Развертывание Horizon (deploy)
Когда вы будете готовы развернуть Horizon на фактическом сервере приложения, вам следует настроить монитор процессов для отслеживания командой php artisan horizon
и перезапустить ее, если она неожиданно завершится. Не волнуйтесь, ниже мы обсудим, как установить монитор процессов.
Во время процесса развертывания приложения вы должны дать команду Horizon завершить процесс, чтобы он был перезапущен монитором процессов и получил изменения кода:
php artisan horizon:terminate
Установка Supervisor
Supervisor – это монитор процессов для операционной системы Linux, который автоматически перезапустит ваш процесс horizon
, если он перестанет выполняться. Чтобы установить Supervisor в Ubuntu, вы можете использовать следующую команду. Если вы не используете Ubuntu, вы, вероятно, можете установить Supervisor с помощью диспетчера пакетов вашей операционной системы:
sudo apt-get install supervisor
Если настройка Supervisor сама по себе кажется утомительной, рассмотрите возможность использования Laravel Forge, который автоматически установит и настроит Supervisor для ваших проектов Laravel.
Настройка Supervisor
Файлы конфигурации супервизора обычно хранятся в каталоге вашего сервера /etc/supervisor/conf.d
. В этом каталоге вы можете создать любое количество файлов конфигурации, которые определяют для супервизора, как следует контролировать процессы. Например, давайте создадим файл horizon.conf
, который запускает и отслеживает процесс horizon
:
[program:horizon]
process_name=%(program_name)s
command=php /home/forge/example.com/artisan horizon
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/example.com/horizon.log
stopwaitsecs=3600
Вы должны убедиться, что значение
stopwaitsecs
больше, чем количество секунд, потребляемых вашим самым длительным выполняемым заданием. В противном случае Supervisor может удалить ваш процесс задания до того, как оно завершит обработку.
Запуск Supervisor
После создания файла конфигурации вы можете обновить конфигурацию Supervisor и запустить отслеживаемые процессы, используя следующие команды:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start horizon
Для получения дополнительной информации о запуске Supervisor обратитесь к документации Supervisor.
Теги
Horizon позволяет назначать “теги” (tags) заданиям, включая почтовые сообщения, широковещательные события, уведомления и прослушиватели событий в очереди. Фактически, Horizon будет интеллектуально и автоматически помечать большинство заданий в зависимости от моделей Eloquent, прикрепленных к заданию. Например, взгляните на следующее задание (job):
<?php
namespace App\Jobs;
use App\Models\Video;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class RenderVideo implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The video instance.
*
* @var \App\Models\Video
*/
public $video;
/**
* Create a new job instance.
*
* @param \App\Models\Video $video
* @return void
*/
public function __construct(Video $video)
{
$this->video = $video;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
Если это задание поставлено в очередь с экземпляром App\Models\Video
с атрибутом id
равным 1
, то оно автоматически получит тег App\Models\Video:1
. Это потому, что Horizon будет искать в свойствах задания любые модели Eloquent. Если модели Eloquent будут найдены, Horizon разумно пометит задание, используя имя класса модели и первичный ключ:
use App\Jobs\RenderVideo;
use App\Models\Video;
$video = Video::find(1);
RenderVideo::dispatch($video);
Самостоятельное тегирование заданий
Если вы хотите самостоятельно определить теги для одного из объектов в очереди, вы можете определить в классе метод “tags()”:
class RenderVideo implements ShouldQueue
{
/**
* Получить теги которые назначаются заданию.
*
* @return array
*/
public function tags()
{
return ['render', 'video:'.$this->video->id];
}
}
Уведомления
При настройке Horizon для отправки уведомлений Slack или SMS необходимо ознакомиться с предварительными условиями для соответствующего канала уведомлений.
Если вы хотите получать уведомления, когда одна из ваших очередей имеет длительное время ожидания, вы можете использовать методы Horizon::routeMailNotificationsTo
, Horizon::routeSlackNotificationsTo
и Horizon::routeSmsNotificationsTo
. Вы можете вызвать эти методы из метода boot
провайдера вашего приложения App\Providers\HorizonServiceProvider
:
/**
* Загрузчик сервисов приложения.
*
* @return void
*/
public function boot()
{
parent::boot();
Horizon::routeSmsNotificationsTo('15556667777');
Horizon::routeMailNotificationsTo('example@example.com');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
}
Настройка пороговых значений времени ожидания уведомлений
Вы можете настроить, сколько секунд будет считаться “долгим ожиданием” в файле конфигурации Horizon config/horizon.php
. Параметр конфигурации waits
в этом файле позволяет вам настраивать пороги ожидания для каждой комбинации соединения/очереди:
'waits' => [
'redis:default' => 60,
'redis:critical,high' => 90,
],
Метрики
Horizon включает панель показателей, которая предоставляет информацию о времени ожидания и пропускной способности вашего задания и очереди. Чтобы заполнить эту информационную панель, вы должны настроить Artisan-команду Horizon snapshot
на запуск каждые пять минут через планировщик (scheduler) вашего приложения:
/**
* Определение расписания для команд.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('horizon:snapshot')->everyFiveMinutes();
}
Удаление невыполненных заданий
Если вы хотите удалить неудавшееся задание, можете использовать команду horizon:forget
. Команда horizon:forget
принимает идентификатор или UUID неудачного задания в качестве своего единственного аргумента:
php artisan horizon:forget 5
Удаление заданий из очередей
Если вы хотите удалить все задания из очереди приложения по умолчанию, то вы можете сделать это с помощью Artisan-команды horizon:clear
:
php artisan horizon:clear
Можно добавить опцию queue
для удаления заданий из определенной очереди:
php artisan horizon:clear --queue=emails