Laravel 地平线

Introduction

Note
在深入了解 Laravel Horizo​​n 之前,您应该熟悉 Laravel 的基础队列服务.如果您还不熟悉 Laravel 提供的基本队列功能,Horizo​​n 会增加 Laravel 的队列功能,这些功能可能会让您感到困惑。

Laravel 地平线 为你的 Laravel 提供漂亮的仪表板和代码驱动的配置Redis队列. Horizo​​n 允许您轻松监控队列系统的关键指标,例如作业吞吐量、运行时间和作业失败。

使用 Horizo​​n 时,所有队列工作器配置都存储在一个简单的配置文件中。通过在版本控制文件中定义应用程序的工作线程配置,您可以在部署应用程序时轻松扩展或修改应用程序的队列工作线程。

Installation

Warning
Laravel Horizo​​n 要求你使用Redis 为您的队列提供动力。因此,您应该确保您的队列连接设置为redis 在你的应用程序中config/queue.php 配置文件。

您可以使用 Composer 包管理器将 Horizo​​n 安装到您的项目中:

composer require laravel/horizon

安装 Horizo​​n 后,使用horizon:install 工匠命令:

php artisan horizon:install

Configuration

发布 Horizo​​n 的资产后,其主要配置文件位于config/horizon.php.此配置文件允许您为您的应用程序配置队列工作器选项。每个配置选项都包含其用途的描述,因此请务必彻底浏览此文件。

Warning
Horizo​​n 使用名为horizon 在内部。此 Redis 连接名称已保留,不应分配给另一个 Redis 连接database.php 配置文件或作为值use 中的选项horizon.php 配置文件。

Environments

安装后,您应该熟悉的主要 Horizo​​n 配置选项是environments 配置选项。此配置选项是您的应用程序运行的一系列环境,并为每个环境定义工作进程选项。默认情况下,此条目包含productionlocal 环境。但是,您可以根据需要自由添加更多环境:

'environments' => [
    'production' => [
        'supervisor-1' => [
            'maxProcesses' => 10,
            'balanceMaxShift' => 1,
            'balanceCooldown' => 3,
        ],
    ],

    'local' => [
        'supervisor-1' => [
            'maxProcesses' => 3,
        ],
    ],
],

当您启动 Horizo​​n 时,它将使用您的应用程序运行环境的工作进程配置选项。通常,环境是由值决定的APP_ENV 环境变量.例如,默认local Horizo​​n 环境配置为启动三个工作进程并自动平衡分配给每个队列的工作进程数。默认的production 环境配置为最多启动 10 个工作进程,并自动平衡分配给每个队列的工作进程数。

Warning
你应该确保environments 你的一部分horizon 配置文件包含每个条目environment 您计划在其上运行 Horizo​​n。

Supervisors

正如您在 Horizo​​n 的默认配置文件中看到的那样,每个环境都可以包含一个或多个“主管”。默认情况下,配置文件将此主管定义为supervisor-1;但是,您可以随意命名您的主管。每个主管基本上负责“监督”一组工作进程,并负责平衡队列中的工作进程。

如果您想定义一组应在该环境中运行的新工作进程,则可以向给定环境添加其他主管。如果您想为应用程序使用的给定队列定义不同的平衡策略或工作进程计数,则可以选择这样做。

默认值

在 Horizo​​n 的默认配置文件中,您会注意到defaults 配置选项。此配置选项指定应用程序的默认值supervisors.主管的默认配置值将合并到每个环境的主管配置中,让您在定义主管时避免不必要的重复。

平衡策略

与 Laravel 的默认队列系统不同,Horizo​​n 允许您从三种 worker 平衡策略中进行选择:simple,auto, 和false.这simple 策略,这是配置文件的默认值,在工作进程之间平均分配传入的作业:

'balance' => 'simple',

auto 策略根据队列的当前工作负载调整每个队列的工作进程数。例如,如果您的notifications 队列有 1,000 个待处理的作业,而您render queue 为空,Horizo​​n 会分配更多的 worker 给你notifications 排队直到队列为空。

当使用auto 策略,你可以定义minProcessesmaxProcesses 配置选项来控制工作进程的最小和最大数量 Horizo​​n 应该向上和向下扩展到:

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

balanceMaxShiftbalanceCooldown 配置值决定了 Horizo​​n 扩展以满足工作人员需求的速度。在上面的示例中,每三秒最多将创建或销毁一个新进程。您可以根据应用程序的需要随意调整这些值。

当。。。的时候balance 选项设置为false,将使用默认的 Laravel 行为,其中队列按照它们在您的配置中列出的顺序进行处理。

仪表盘授权

Horizo​​n 在/horizon 网址。默认情况下,您只能在local 环境。然而,在你的app/Providers/HorizonServiceProvider.php 文件,有一个授权门 定义。此授权门控制对 Horizo​​n 的访问non-local 环境。您可以根据需要自由修改此门以限制对 Horizo​​n 安装的访问:

/**
 * Register the Horizon gate.
 *
 * This gate determines who can access Horizon in non-local environments.
 */
protected function gate(): void
{
    Gate::define('viewHorizon', function (User $user) {
        return in_array($user->email, [
            'taylor@laravel.com',
        ]);
    });
}

替代身份验证策略

请记住,Laravel 会自动将经过身份验证的用户注入到门关闭中。如果您的应用程序通过其他方法(例如 IP 限制)提供 Horizo​​n 安全性,那么您的 Horizo​​n 用户可能不需要“登录”。因此,您需要更改function (User $user) 上面的关闭签名function (User $user = null) 为了强制 Laravel 不需要身份验证。

沉默的工作

有时,您可能对查看由您的应用程序或第三方包分派的某些作业不感兴趣。这些作业不会占用“已完成作业”列表中的空间,您可以将它们静音。首先,将作业的类名添加到silenced 应用程序中的配置选项horizon 配置文件:

'silenced' => [
    App\Jobs\ProcessPodcast::class,
],

或者,您希望沉默的工作可以实现Laravel\Horizon\Contracts\Silenced 界面。如果一个作业实现了这个接口,它会自动被静音,即使它不存在于silenced 配置数组:

use Laravel\Horizon\Contracts\Silenced;

class ProcessPodcast implements ShouldQueue, Silenced
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    // ...
}

升级地平线

升级到 Horizo​​n 的新主要版本时,请务必仔细查看升级指南.此外,当升级到任何新的 Horizo​​n 版本时,您应该重新发布 Horizo​​n 的资产:

php artisan horizon:publish

为了使资产保持最新并避免在未来的更新中出现问题,您可以添加vendor:publish --tag=laravel-assets 命令到post-update-cmd 应用程序中的脚本composer.json 文件:

{
    "scripts": {
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ]
    }
}

奔跑的地平线

在您的应用程序中配置主管和工作人员后config/horizon.php 配置文件,你可以使用horizon 工匠命令。此单个命令将启动当前环境的所有已配置工作进程:

php artisan horizon

您可以暂停 Horizo​​n 进程并指示它继续使用horizon:pausehorizon:continue 工匠命令:

php artisan horizon:pause

php artisan horizon:continue

您也可以暂停并继续特定的地平线supervisors 使用horizon:pause-supervisorhorizon:continue-supervisor 工匠命令:

php artisan horizon:pause-supervisor supervisor-1

php artisan horizon:continue-supervisor supervisor-1

您可以使用horizon:status 工匠命令:

php artisan horizon:status

您可以使用以下方式优雅地终止 Horizo​​n 进程horizon:terminate 工匠命令。当前正在处理的任何作业都将完成,然后 Horizo​​n 将停止执行:

php artisan horizon:terminate

部署地平线

当您准备好将 Horizo​​n 部署到应用程序的实际服务器时,您应该配置一个进程监视器来监视php artisan horizon 命令并在它意外退出时重新启动它。别担心,我们将在下面讨论如何安装进程监视器。

在应用程序的部署过程中,您应该指示 Horizo​​n 进程终止,以便进程监视器重新启动它并接收您的代码更改:

php artisan horizon:terminate

安装主管

Supervisor 是 Linux 操作系统的进程监视器,会自动重启你的horizon 如果它停止执行则处理。要在 Ubuntu 上安装 Supervisor,您可以使用以下命令。如果您不使用 Ubuntu,您可以使用操作系统的包管理器安装 Supervisor:

sudo apt-get install supervisor

Note
如果自己配置 Supervisor 听起来让人不知所措,请考虑使用Laravel 锻造,它将自动为您的 Laravel 项目安装和配置 Supervisor。

主管配置

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

在定义您的 Supervisor 配置时,您应该确保stopwaitsecs 大于运行时间最长的作业消耗的秒数。否则,Supervisor 可能会在作业完成处理之前将其杀死。

Warning
虽然上述示例对基于 Ubuntu 的服务器有效,但 Supervisor 配置文件的位置和文件扩展名可能因其他服务器操作系统而异。请查阅您服务器的文档以获取更多信息。

首任主管

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

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start horizon

Note
有关运行 Supervisor 的更多信息,请参阅主管文件.

Tags

Horizo​​n 允许您为作业分配“标签”,包括邮件、广播事件、通知和排队的事件侦听器。事实上,Horizo​​n 会智能地自动标记大多数作业,这取决于附加到作业的 Eloquent 模型。例如,看看下面的工作:

<?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;

    /**
     * Create a new job instance.
     */
    public function __construct(
        public Video $video,
    ) {}

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        // ...
    }
}

如果此作业排队App\Models\Video 有一个实例id 的属性1,它会自动接收标签App\Models\Video:1.这是因为 Horizo​​n 将在作业的属性中搜索任何 Eloquent 模型。如果找到 Eloquent 模型,Horizo​​n 将使用模型的类名和主键智能地标记作业:

use App\Jobs\RenderVideo;
use App\Models\Video;

$video = Video::find(1);

RenderVideo::dispatch($video);

手动标记作业

如果你想为你的队列对象之一手动定义标签,你可以定义一个tags 类上的方法:

class RenderVideo implements ShouldQueue
{
    /**
     * Get the tags that should be assigned to the job.
     *
     * @return array<int, string>
     */
    public function tags(): array
    {
        return ['render', 'video:'.$this->video->id];
    }
}

Notifications

Warning
配置 Horizo​​n 以发送 Slack 或 SMS 通知时,您应该查看相关通知渠道的先决条件.

如果您想在其中一个队列等待时间较长时收到通知,您可以使用Horizon::routeMailNotificationsTo,Horizon::routeSlackNotificationsTo, 和Horizon::routeSmsNotificationsTo 方法。您可以从boot 你的应用程序的方法App\Providers\HorizonServiceProvider:

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    parent::boot();

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

配置通知等待时间阈值

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

'waits' => [
    'redis:default' => 60,
    'redis:critical,high' => 90,
],

Metrics

Horizo​​n 包括一个指标仪表板,它提供有关您的作业和队列等待时间以及吞吐量的信息。为了填充此仪表板,您应该配置 Horizo​​n 的snapshot Artisan 命令通过您的应用程序每五分钟运行一次scheduler:

/**
 * Define the application's command schedule.
 */
protected function schedule(Schedule $schedule): void
{
    $schedule->command('horizon:snapshot')->everyFiveMinutes();
}

删除失败的作业

如果你想删除一个失败的作业,你可以使用horizon:forget 命令。这horizon:forget 命令接受失败作业的 ID 或 UUID 作为其唯一参数:

php artisan horizon:forget 5

从队列中清除作业

如果您想从应用程序的默认队列中删除所有作业,您可以使用horizon:clear 工匠命令:

php artisan horizon:clear

你可以提供queue 从特定队列中删除作业的选项:

php artisan horizon:clear --queue=emails
豫ICP备18041297号-2