Laravel Horizon

介绍

Horizon 为你的Laravel Redis队列提供了一个美观的控制面板和代码驱动的配置;它可以方便的监控队列系统的关键指标:任务吞吐量、运行时间、工作故障。

所有的worker配置存储在一个简单的配置文件中,你可以在整个团队都可以进行协作的地方进行源码控制。

1240

安装

提示: 要确保队列连接在queue 配置文件的redis项已经正确设置。

可以使用Composer将Horization安装到你的Laravel项目里:

  1. composer require laravel/horizon

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

  1. php artisan horizon:install

配置

Horizon资源发布之后,他的主要配置文件会被分配到config/horizon.php文件。可以用这个配置文件配置工作选项,每个配置选项包含一个用途描述,因此要仔细研究这个文件。

注意:要确保 horizon 配置文件的 environments 部分包含你了你计划在horizon上运行的每个环境选项。

Balance 选项

Horizon 允许你从三个平衡策略中进行选择:simpleauto, 和 falsesimple 策略是配置文件的默认选项,它会在进程之间平均分配进入的任务:

  1. 'balance' => 'simple',

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

当使用auto策略时,你可以定义 minProcessesmaxProcesses 的配置选项来控制进程的最小和最大数量。

  1. 'environments' => [
  2. 'production' => [
  3. 'supervisor-1' => [
  4. 'connection' => 'redis',
  5. 'queue' => ['default'],
  6. 'balance' => 'auto',
  7. 'minProcesses' => 1,
  8. 'maxProcesses' => 10,
  9. 'tries' => 3,
  10. ],
  11. ],
  12. ],

任务清理

horizon 配置文件允许您配置最近的和失败的任务应该持续多长时间(以分钟为单位)。默认情况下,保存最近的作业一个小时,保存失败的作业一个星期:

  1. 'trim' => [
  2. 'recent' => 60,
  3. 'failed' => 10080,
  4. ],

控制面板授权

Horizon在 /horizon 上显示了一个控制面板。默认情况下,你只能在local环境中访问这个面板。在你的 app/Providers/HorizonServiceProvider.php 文件中,有一个 gate 方法。此授权门控制着在非本地环境中对Horizon进行的访问。您可以根据需要修改此门,来限制对Horizon安装的访问:

  1. /**
  2. * 注册授权门.
  3. *
  4. * 此门决定了谁可以在非本地环境中访问Horizon
  5. *
  6. * @return void
  7. */
  8. protected function gate()
  9. {
  10. Gate::define('viewHorizon', function ($user) {
  11. return in_array($user->email, [
  12. 'taylor@laravel.com',
  13. ]);
  14. });
  15. }

提示:记住Laravel会自动将 authenticated 用户注入到Gate中。如果你的应用通过另一种方式提供了Horizon的安全性,比如IP限制,那么你的Horizon用户可能不需要“登录”。因此,你需要将上面的 function ($user)更改为 function ($user = null),以强制Laravel不需要身份验证。

升级 Horizon

当你升级到Horizon的一个新主要版本时,你需要仔细阅读升级指南.另外,你应该重新发布Horizon的资源:

  1. php artisan horizon:publish

运行 Horizon

一旦在 config/horizon.php 中配置了你的workers。你可以使用 horizon Artisan命令启动Horizon。只需这一个命令你就可以启动你的所有已配置的workers:

  1. php artisan horizon

可以暂停Horizon进程,并使用horizon:pausehorizon:continue Artisan命令指示它继续处理任务:

  1. php artisan horizon:pause
  2. php artisan horizon:continue

可以使用 horizon:status Artisan命令检查Horizon进程的当前状态:

  1. php artisan horizon:status

您可以使用 horizon:terminate Artisan命令优雅地终止机器上的主Horizon进程。Horizon会等当前正在处理的所有任务都完成后退出:

  1. php artisan horizon:terminate

部署 Horizon

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

安装 Supervisor

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

  1. sudo apt-get install supervisor

提示:如果你觉得自己配置Supervisor很困难,可以考虑使用Laravel Forge,它将自动为您的Laravel项目安装和配置Supervisor。

Supervisor 配置

Supervisor配置文件通常存储在 /etc/supervisor/conf.d 目录下。在此目录中,你可以创建任意数量的配置文件,这些配置文件会告诉supervisor如何监视你的进程。例如,让我们创建一个 horizon.conf 文件,它启动并监视一个horizon进程:

  1. [program:horizon]
  2. process_name=%(program_name)s
  3. command=php /home/forge/app.com/artisan horizon
  4. autostart=true
  5. autorestart=true
  6. user=forge
  7. redirect_stderr=true
  8. stdout_logfile=/home/forge/app.com/horizon.log
  9. stopwaitsecs=3600

注意: 要确保 stopwaitsecs 的值大于运行时间最长的任务所消耗的秒数。否则,Supervisor 可能会在工作完成前终止任务。

启动 Supervisor

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

  1. sudo supervisorctl reread
  2. sudo supervisorctl update
  3. sudo supervisorctl start horizon

关于Supervisor的更多信息, 可以查阅 Supervisor 文档.

标记

Horizon允许您将 tags 分配给任务,包括邮件、事件广播、通知和排队的事件监听器。实际上,Horizon会根据附加到作业上的有Eloquent模型,智能地、自动地标记大多数任务。例如,看看下面的任务:

  1. <?php
  2. namespace App\Jobs;
  3. use App\Video;
  4. use Illuminate\Bus\Queueable;
  5. use Illuminate\Contracts\Queue\ShouldQueue;
  6. use Illuminate\Foundation\Bus\Dispatchable;
  7. use Illuminate\Queue\InteractsWithQueue;
  8. use Illuminate\Queue\SerializesModels;
  9. class RenderVideo implements ShouldQueue
  10. {
  11. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  12. /**
  13. * video实例
  14. *
  15. * @var \App\Video
  16. */
  17. public $video;
  18. /**
  19. * 创建一个新的任务实例
  20. *
  21. * @param \App\Video $video
  22. * @return void
  23. */
  24. public function __construct(Video $video)
  25. {
  26. $this->video = $video;
  27. }
  28. /**
  29. * 执行任务
  30. *
  31. * @return void
  32. */
  33. public function handle()
  34. {
  35. //
  36. }
  37. }

如果此任务与 App\Video 实例一起排队,且该实例的 id1,则该作业将自动接收App\Video:1 标记。这是因为Horizon将为任何有Eloquent的模型检查任务的属性。如果找到了有Eloquent的模型,Horizon将智能地使用模型的类名和主键标记任务:

  1. $video = App\Video::find(1);
  2. App\Jobs\RenderVideo::dispatch($video);

手动标记

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

  1. class RenderVideo implements ShouldQueue
  2. {
  3. /**
  4. * 获取应该分配给任务的标记
  5. *
  6. * @return array
  7. */
  8. public function tags()
  9. {
  10. return ['render', 'video:'.$this->video->id];
  11. }
  12. }

通知

注意: 如果要发送 Slack 或 SMS 通知,要配置Horizon应该检查,应该回顾一下 相关通知驱动程序的先决条件.

如果你希望在一个队列有较长的等待时间时得到通知,您可以使用 Horizon::routeMailNotificationsToHorizon::routeSmsNotificationsToHorizon::routeSmsNotificationsTo 方法。你可以从你的应用程序的HorizonServiceProvider 调用这些方法:

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

配置通知等待时间阈值

您可以在 config/horizon.php的配置文件中配置多少秒算是长等待。你可以用该文件中的 waits 配置选项控制每个 连接/队列 组合的长等待阈值:

  1. 'waits' => [
  2. 'redis:default' => 60,
  3. ],

指标

Horizon有一个指标控制面板,它提供了任务和队列的等待时间和吞吐量等信息。要让这些信息显示在这个控制面板上,你应该配置Horizon的 snapshot Artisan命令,通过你的应用程序的调度器每五分钟运行一次:

  1. /**
  2. * 定义应用程序的命令调度
  3. *
  4. * @param \Illuminate\Console\Scheduling\Schedule $schedule
  5. * @return void
  6. */
  7. protected function schedule(Schedule $schedule)
  8. {
  9. $schedule->command('horizon:snapshot')->everyFiveMinutes();
  10. }

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

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接 我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

Laravel China 社区:https://learnku.com/docs/laravel/7.x/horizon/7514