Laravel Horizon
介绍
Horizon 为您的 Laravel 驱动的 Redis 队列提供了一个美观的仪表板和代码驱动的配置。Horizon 允许您轻松监控队列系统的关键指标,如作业吞吐量、运行时间和作业失败。
所有的工作者配置都存储在一个简单的配置文件中,使您的配置可以保存在源代码控制中,便于整个团队协作。
安装
由于其使用异步进程信号,Horizon 需要 PHP 7.1+。其次,您应确保在 queue
配置文件中将队列驱动程序设置为 redis
。
您可以使用 Composer 将 Horizon 安装到您的 Laravel 项目中:
composer require laravel/horizon "^2.0"
安装 Horizon 后,使用 vendor:publish
Artisan 命令发布其资产:
php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"
配置
发布 Horizon 的资产后,其主要配置文件将位于 config/horizon.php
。此配置文件允许您配置工作者选项,每个配置选项都包含其目的的描述,因此请务必仔细查看此文件。
平衡选项
Horizon 允许您从三种平衡策略中进行选择:simple
、auto
和 false
。默认的 simple
策略将传入的作业均匀地分配到各个进程:
'balance' => 'simple',
auto
策略根据队列的当前工作负载调整每个队列的工作者进程数量。例如,如果您的 notifications
队列有 1,000 个等待作业,而您的 render
队列为空,Horizon 将为您的 notifications
队列分配更多的工作者,直到其为空。当 balance
选项设置为 false
时,将使用默认的 Laravel 行为,即按配置中列出的顺序处理队列。
仪表板认证
Horizon 在 /horizon
处公开一个仪表板。默认情况下,您只能在 local
环境中访问此仪表板。要为仪表板定义更具体的访问策略,您应使用 Horizon::auth
方法。auth
方法接受一个回调,该回调应返回 true
或 false
,指示用户是否应有权访问 Horizon 仪表板。通常,您应在 AppServiceProvider
的 boot
方法中调用 Horizon::auth
:
Horizon::auth(function ($request) {
// return true / false;
});
运行 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];
}
}
通知
在使用通知之前,您应将 guzzlehttp/guzzle
Composer 包添加到您的项目中。在配置 Horizon 以发送 SMS 通知时,您还应查看 Nexmo 通知驱动程序的先决条件。
如果您希望在队列等待时间过长时收到通知,可以使用 Horizon::routeMailNotificationsTo
、Horizon::routeSlackNotificationsTo
和 Horizon::routeSmsNotificationsTo
方法。您可以从应用程序的 AppServiceProvider
中调用这些方法:
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();
}