Horizon 队列管理工具

未匹配的标注
本文档最新版为 8.x,旧版本可能放弃维护,推荐阅读最新版!

Laravel Horizon

简介

Horizon 提供了一个漂亮的仪表盘,并且可以通过代码配置你的 Laravel Redis 队列,同时它允许你轻易的监控你的队列系统中诸如任务吞吐量,运行时间和失败任务等关键指标。.

所有的配置项都存放在一个简单的配置文件中,从而允许你将它放在团队的协同版本控制中,方便团队协作。

wfych538yj.png!large

安装

注意:你应该确保 queue 配置文件中设置了 redis 队列驱动。

你应该使用 Composer 来安为你的 Laravel 项目安装 Horizon:

composer require laravel/horizon

安装完成后,使用 horizon:install 发布 Artisan 命令:

php artisan horizon:install

你还应该创建 failed_jobs 表,Laravel 将使用该表来存储任何 failed queue jobs:

php artisan queue:failed-table

php artisan migrate

升级 Horizon

当升级到 Horizon 的一个新的主要版本时,你必须仔细检查 the upgrade guide.

此外,你应该重新发布 Horizon 的资源文件:

php artisan horizon:assets

配置

发布 Horizon 相关文件后,他的主要配置文件会放在 config/horizon.php。你可以在这个文件中配置队列相关选项,并且每个配置项都有详细的使用说明,请详细阅读此文件。

注意:你应确保 horizon 配置文件的 environments 部分包含你计划在其上运行 Horizon 的每个环境的条目。

均衡配置

Horizon 提供了三种均衡策略: simpleauto ,和 false 。默认的是 simple , 会将收到的任务均分给队列进程:

'balance' => 'simple',

auto 策略会根据当前的工作量调整每个队列的工作进程任务数量。例如:如果 notifications 队列有 1000 个待执行任务,但是你的 render 队列是空的,Horizon 会分配更多的工作进程给 notifications 队列,直到 notifications 队列中所有任务执行完成。当配置项 balance 配置为 false ,Horizon 会使用 Laravel 默认执行行为,它将按照配置中列出的顺序处理队列任务。

当使用 auto 策略时,您可以定义 minProcessesmaxProcesses 配置选项,以控制最小和最大进程数范围应向上和向下扩展到:

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

任务修整

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

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

仪表盘权限验证

Horizon 仪表盘路由是 /horizon. 。 默认情况下,你只能在 local 环境下访问仪表盘。在你的 app/Providers/HorizonServiceProvider.php 文件中,有一个 gate 方法。这里授权控制 非本地 环境中对 Horizon 的访问。 你可以根据需要随意修改此门面,以限制对 Horizon 安装的访问:

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

注意:记住,Laravel会自动将 authenticated 用户注入到 gate 方法。如果您的应用程序通过其他方法(如IP限制)提供 Horizon 安全,那么 Horizon 用户可能不需要“登录”。因此,您需要将上面的 function ($user) 更改为 function ($user = null)以使 Laravel 不需要进行身份验证。

运行 Horizon

当在 config/horizon.php 文件中配置好了你的队列执行进程后,你就可以使用 horizon Artisan 命令启动 Horizon。只需要一条命令语句即可启动所有配置好的队列进程:

php artisan horizon

你也可以使用 horizon:pausehorizon:continue Artisan 命令来暂停或继续执行队列任务:

php artisan horizon:pause

php artisan horizon:continue

你可以使用 horizon:terminate Artisan 命令优雅的终止 Horizon 主进程。Horizon 会把正在执行的任务处理完毕后退出:

php artisan horizon:terminate

部署 Horizon

如果你将 Horizon 部署到线上服务器时,则需要配置一个进程监控器来检测 php artisan horizon 命令,在它意外退出时自动重启。上线新代码时则需要该进程监控器终止 Horizon 进程并以修改后的代码重启 Horizon。

Supervisor 配置

如果你使用 Supervisor 进程监控器管理你的 horizon 进程,那么以下配置文件则可满足需求:

[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

Tip:如果你不喜欢自己维护服务器,可以考虑使用 Laravel Forge 。Forge 提供了运行一个带有 Horizon 的现代、强大的 Laravel 应用所需要的 PHP7+ 及其他所有环境。

标签

Horizon 允许你对任务分配「标签」,包括邮件,事件广播,通知和队列的事件监听器。事实上,Horizon 会智能并且自动根据任务携带 Eloquent 模型给大多数任务标记标签,如下任务示例:

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

    /**
     * video 实例
     *
     * @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 将会智能的用该模型的类名和主键为任务标记上标签:

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

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

自定义标签

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

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

通知

Note: 配置Horizon以发送Slack或SMS通知时,应查看 相关通知驱动程序的前提条件.

如果需要在队列等待时间过长时发起通知,可以在应用的 HorizonServiceProvider 中调用 Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo , 和 Horizon::routeSmsNotificationsTo 方法:

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

配置等待时间过长的阈值

你可以在 config/horizon.php 配置文件中设置等待时间过长的具体秒数。 waits 配置项可以针对每一个 链接 / 队列 配置阈值:

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

Metrics

Horizon 包含一个 Metrics 仪表盘,它可以提供任务和队列等待时间和吞吐量信息,为了填充此仪表盘,你需要通过应用的任务调度器配置Horizon 的 snapshot Artisan命令每五分钟运行一次。

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

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
上一篇 下一篇
Summer
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
贡献者:8
讨论数量: 1
发起讨论 只看当前版本


Kiddo
重启 horizon 后,需要再手动重启 queue 吗?
0 个点赞 | 1 个回复 | 问答 | 课程版本 6.x