Laravel Horizon
介绍
Horizon 为您的 Laravel 驱动的 Redis 队列提供了一个美观的仪表板和代码驱动的配置。Horizon 允许您轻松监控队列系统的关键指标,如作业吞吐量、运行时间和作业失败。
所有的工作者配置都存储在一个简单的配置文件中,使您的配置可以保留在源代码管理中,方便整个团队协作。
安装
您应确保在 queue
配置文件中将队列连接设置为 redis
。
您可以使用 Composer 将 Horizon 安装到您的 Laravel 项目中:
composer require laravel/horizon
安装 Horizon 后,使用 horizon:install
Artisan 命令发布其资产:
php artisan horizon:install
您还应该创建 failed_jobs
表,Laravel 将使用该表存储任何失败的队列作业:
php artisan queue:failed-table
php artisan migrate
升级 Horizon
在升级到 Horizon 的新主要版本时,务必仔细查看升级指南。
此外,您应该重新发布 Horizon 的资产:
php artisan horizon:assets
配置
发布 Horizon 的资产后,其主要配置文件将位于 config/horizon.php
。此配置文件允许您配置工作者选项,每个配置选项都包含其用途的描述,因此请务必仔细探索此文件。
您应确保 horizon
配置文件的 environments
部分包含您计划运行 Horizon 的每个环境的条目。
平衡选项
Horizon 允许您从三种平衡策略中进行选择:simple
、auto
和 false
。配置文件的默认策略是 simple
,它将传入作业均匀分配到进程之间:
'balance' => 'simple',
auto
策略根据队列的当前工作负载调整每个队列的工作者进程数量。例如,如果您的 notifications
队列有 1,000 个等待作业,而您的 render
队列为空,Horizon 将为您的 notifications
队列分配更多的工作者,直到它为空。当 balance
选项设置为 false
时,将使用默认的 Laravel 行为,即按配置中列出的顺序处理队列。
使用 auto
策略时,您可以定义 minProcesses
和 maxProcesses
配置选项,以控制 Horizon 应该扩展和缩减到的最小和最大进程数:
'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 安装的访问:
/**
* 注册 Horizon 门控。
*
* 此门控决定谁可以在非本地环境中访问 Horizon。
*
* @return void
*/
protected function gate()
{
Gate::define('viewHorizon', function ($user) {
return in_array($user->email, [
'taylor@laravel.com',
]);
});
}
请记住,Laravel 会自动将已认证的用户注入到 Gate 中。如果您的应用程序通过其他方法(如 IP 限制)提供 Horizon 安全性,那么您的 Horizon 用户可能不需要“登录”。因此,您需要将上面的 function ($user)
更改为 function ($user = null)
,以强制 Laravel 不要求身份验证。
运行 Horizon
配置好 config/horizon.php
配置文件中的工作者后,您可以使用 horizon
Artisan 命令启动 Horizon。此单个命令将启动您配置的所有工作者:
php artisan horizon
您可以暂停 Horizon 进程,并使用 horizon:pause
和 horizon:continue
Artisan 命令指示其继续处理作业:
php artisan horizon:pause
php artisan horizon:continue
您可以使用 horizon:terminate
Artisan 命令优雅地终止您机器上的主 Horizon 进程。Horizon 当前正在处理的任何作业将完成,然后 Horizon 将退出:
php artisan horizon:terminate
部署 Horizon
如果您将 Horizon 部署到实时服务器,您应该配置一个进程监视器来监视 php artisan 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
如果您不习惯管理自己的服务器,请考虑使用 Laravel Forge。Forge 提供 PHP 7+ 服务器,具备运行现代、强大的 Laravel 应用程序与 Horizon 所需的一切。
标签
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;
/**
* 视频实例。
*
* @var \App\Video
*/
public $video;
/**
* 创建一个新的作业实例。
*
* @param \App\Video $video
* @return void
*/
public function __construct(Video $video)
{
$this->video = $video;
}
/**
* 执行作业。
*
* @return void
*/
public function handle()
{
//
}
}
如果此作业使用 id
为 1
的 App\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];
}
}
通知
在配置 Horizon 以发送 Slack 或 SMS 通知时,您应查看相关通知驱动程序的先决条件。
如果您希望在某个队列有长时间等待时收到通知,可以使用 Horizon::routeMailNotificationsTo
、Horizon::routeSlackNotificationsTo
和 Horizon::routeSmsNotificationsTo
方法。您可以从应用程序的 HorizonServiceProvider
中调用这些方法:
Horizon::routeMailNotificationsTo('example@example.com');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
Horizon::routeSmsNotificationsTo('15556667777');
配置通知等待时间阈值
您可以在 config/horizon.php
配置文件中配置多少秒被视为“长时间等待”。此文件中的 waits
配置选项允许您控制每个连接/队列组合的长时间等待阈值:
'waits' => [
'redis:default' => 60,
],
指标
Horizon 包含一个指标仪表板,提供有关作业和队列等待时间及吞吐量的信息。为了填充此仪表板,您应配置 Horizon 的 snapshot
Artisan 命令通过应用程序的调度器每五分钟运行一次:
/**
* 定义应用程序的命令调度。
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('horizon:snapshot')->everyFiveMinutes();
}