Skip to content

Laravel Horizon

介绍

Horizon 为您的 Laravel 驱动的 Redis 队列提供了一个美观的仪表板和代码驱动的配置。Horizon 允许您轻松监控队列系统的关键指标,如作业吞吐量、运行时间和作业失败。

所有的工作者配置都存储在一个简单的配置文件中,使您的配置可以保存在源代码控制中,便于整个团队协作。

安装

exclamation

您应确保在 queue 配置文件中将队列驱动程序设置为 redis

您可以使用 Composer 将 Horizon 安装到您的 Laravel 项目中:

php
composer require laravel/horizon

安装 Horizon 后,使用 horizon:install Artisan 命令发布其资产:

php
php artisan horizon:install

您还应该创建 failed_jobs 表,Laravel 将使用该表存储任何失败的队列作业

php
php artisan queue:failed-table

php artisan migrate

配置

发布 Horizon 的资产后,其主要配置文件将位于 config/horizon.php。此配置文件允许您配置工作者选项,每个配置选项都包含其目的的描述,因此请务必仔细探索此文件。

平衡选项

Horizon 允许您从三种平衡策略中进行选择:simpleautofalsesimple 策略是配置文件的默认设置,将传入作业均匀分配到各个进程:

php
'balance' => 'simple',

auto 策略根据队列的当前工作负载调整每个队列的工作者进程数量。例如,如果您的 notifications 队列有 1,000 个等待作业,而您的 render 队列为空,Horizon 将为您的 notifications 队列分配更多的工作者,直到其为空。当 balance 选项设置为 false 时,将使用默认的 Laravel 行为,即按配置中列出的顺序处理队列。

作业修剪

horizon 配置文件允许您配置最近和失败作业应保留多长时间(以分钟为单位)。默认情况下,最近的作业保留一小时,而失败的作业保留一周:

php
'trim' => [
    'recent' => 60,
    'failed' => 10080,
],

仪表板授权

Horizon 在 /horizon 处公开一个仪表板。默认情况下,您只能在 local 环境中访问此仪表板。在您的 app/Providers/HorizonServiceProvider.php 文件中,有一个 gate 方法。此授权门控在非本地环境中控制对 Horizon 的访问。您可以根据需要修改此门控以限制对您的 Horizon 安装的访问:

php
/**
 * 注册 Horizon 门控。
 *
 * 此门控决定谁可以在非本地环境中访问 Horizon。
 *
 * @return void
 */
protected function gate()
{
    Gate::define('viewHorizon', function ($user) {
        return in_array($user->email, [
            'taylor@laravel.com',
        ]);
    });
}

运行 Horizon

一旦您在 config/horizon.php 配置文件中配置了您的工作者,您可以使用 horizon Artisan 命令启动 Horizon。此单个命令将启动您配置的所有工作者:

php
php artisan horizon

您可以暂停 Horizon 进程并指示其继续处理作业,使用 horizon:pausehorizon:continue Artisan 命令:

php
php artisan horizon:pause

php artisan horizon:continue

您可以使用 horizon:terminate Artisan 命令优雅地终止您机器上的主 Horizon 进程。Horizon 当前正在处理的任何作业将被完成,然后 Horizon 将退出:

php
php artisan horizon:terminate

部署 Horizon

如果您将 Horizon 部署到实时服务器,您应该配置一个进程监视器来监视 php artisan horizon 命令,并在其意外退出时重新启动它。当将新代码部署到服务器时,您需要指示主 Horizon 进程终止,以便您的进程监视器可以重新启动它并接收您的代码更改。

Supervisor 配置

如果您使用 Supervisor 进程监视器来管理您的 horizon 进程,以下配置文件应该足够:

php
[program:horizon]
process_name=%(program_name)s
command=php /home/forge/app.com/artisan horizon
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/app.com/horizon.log
lightbulb

如果您对管理自己的服务器感到不舒服,请考虑使用 Laravel Forge。Forge 提供 PHP 7+ 服务器,具备运行现代、强大的 Laravel 应用程序与 Horizon 所需的一切。

标签

Horizon 允许您为作业分配“标签”,包括邮件、事件广播、通知和排队的事件监听器。事实上,Horizon 将根据附加到作业的 Eloquent 模型智能地自动标记大多数作业。例如,看看以下作业:

php
<?php

namespace App\Jobs;

use App\Video;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class RenderVideo implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * 视频实例。
     *
     * @var \App\Video
     */
    public $video;

    /**
     * 创建一个新的作业实例。
     *
     * @param  \App\Video  $video
     * @return void
     */
    public function __construct(Video $video)
    {
        $this->video = $video;
    }

    /**
     * 执行作业。
     *
     * @return void
     */
    public function handle()
    {
        //
    }
}

如果此作业使用 id1App\Video 实例排队,它将自动接收标签 App\Video:1。这是因为 Horizon 将检查作业的属性以查找任何 Eloquent 模型。如果找到 Eloquent 模型,Horizon 将使用模型的类名和主键智能地标记作业:

php
$video = App\Video::find(1);

App\Jobs\RenderVideo::dispatch($video);

手动标记

如果您希望手动定义队列对象的标签,可以在类上定义一个 tags 方法:

php
class RenderVideo implements ShouldQueue
{
    /**
     * 获取应分配给作业的标签。
     *
     * @return array
     */
    public function tags()
    {
        return ['render', 'video:'.$this->video->id];
    }
}

通知

lightbulb

在使用通知之前,您应将 guzzlehttp/guzzle Composer 包添加到您的项目中。在配置 Horizon 以发送 SMS 通知时,您还应查看 Nexmo 通知驱动程序的先决条件

如果您希望在队列等待时间过长时收到通知,可以使用 Horizon::routeMailNotificationsToHorizon::routeSlackNotificationsToHorizon::routeSmsNotificationsTo 方法。您可以从应用程序的 HorizonServiceProvider 中调用这些方法:

php
Horizon::routeMailNotificationsTo('example@example.com');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
Horizon::routeSmsNotificationsTo('15556667777');

配置通知等待时间阈值

您可以在 config/horizon.php 配置文件中配置多少秒被视为“长等待”。此文件中的 waits 配置选项允许您控制每个连接/队列组合的长等待阈值:

php
'waits' => [
    'redis:default' => 60,
],

指标

Horizon 包含一个指标仪表板,提供有关作业和队列等待时间和吞吐量的信息。为了填充此仪表板,您应配置 Horizon 的 snapshot Artisan 命令通过应用程序的调度器每五分钟运行一次:

php
/**
 * 定义应用程序的命令调度。
 *
 * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
 * @return void
 */
protected function schedule(Schedule $schedule)
{
    $schedule->command('horizon:snapshot')->everyFiveMinutes();
}