Skip to content
赞助商赞助商赞助商
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

Laravel Horizon

介绍

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

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

安装

NOTE

您应确保在 queue 配置文件中将队列连接设置为 redis

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

php
composer require laravel/horizon ~3.0

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

php
php artisan horizon:install

配置

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

NOTE

您应确保 horizon 配置文件的 environments 部分包含您计划运行 Horizon 的每个环境的条目。

平衡选项

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

php
'balance' => 'simple',

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

使用 auto 策略时,您可以定义 minProcessesmaxProcesses 配置选项,以控制 Horizon 应该扩展和缩减到的最小和最大进程数。minProcesses 值指定每个队列的最小进程数,而 maxProcesses 值指定所有队列的最大进程数:

php
'environments' => [
    'production' => [
        'supervisor-1' => [
            'connection' => 'redis',
            'queue' => ['default'],
            'balance' => 'auto',
            'minProcesses' => 1,
            'maxProcesses' => 10,
            'tries' => 3,
        ],
    ],
],

作业修剪

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',
        ]);
    });
}

NOTE

请记住,Laravel 会自动将已认证的用户注入到 Gate 中。如果您的应用程序通过其他方法(如 IP 限制)提供 Horizon 安全性,则您的 Horizon 用户可能不需要“登录”。因此,您需要将上面的 function ($user) 更改为 function ($user = null),以强制 Laravel 不要求身份验证。

升级 Horizon

升级到 Horizon 的新主要版本时,您需要仔细查看升级指南

此外,您应该重新发布 Horizon 的资产:

php
php artisan horizon:assets

运行 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:status Artisan 命令检查 Horizon 进程的当前状态:

php
php artisan horizon:status

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

php
php artisan horizon:terminate

部署 Horizon

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

安装 Supervisor

Supervisor 是 Linux 操作系统的进程监视器,如果 horizon 进程失败,它将自动重新启动。要在 Ubuntu 上安装 Supervisor,您可以使用以下命令:

php
sudo apt-get install supervisor

NOTE

如果自己配置 Supervisor 听起来很复杂,可以考虑使用 Laravel Forge,它会自动为您的 Laravel 项目安装和配置 Supervisor。

Supervisor 配置

Supervisor 配置文件通常存储在 /etc/supervisor/conf.d 目录中。在此目录中,您可以创建任意数量的配置文件,指示 Supervisor 如何监视您的进程。例如,让我们创建一个 horizon.conf 文件来启动和监视一个 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
stopwaitsecs=3600

NOTE

您应确保 stopwaitsecs 的值大于最长运行作业消耗的秒数。否则,Supervisor 可能会在作业完成处理之前将其终止。

启动 Supervisor

创建配置文件后,您可以使用以下命令更新 Supervisor 配置并启动进程:

php
sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start horizon

有关 Supervisor 的更多信息,请查阅 Supervisor 文档

标签

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

php
<?php

namespace App\Jobs;

use App\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;

    /**
     * 视频实例。
     *
     * @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];
    }
}

通知

NOTE

在配置 Horizon 发送 Slack 或 SMS 通知时,您应查看相关通知驱动程序的先决条件

如果您希望在队列等待时间过长时收到通知,可以使用 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();
}