Laravel Horizon
Table of Contents
Introduction
NOTE
Laravel Horizon について詳しく調べる前に、まずは Laravel の基本的なqueueserviceに慣れておくべきです。Horizon は Laravel の queue に追加の機能を追加しますが、それらの機能は、すでに Laravel が提供する基本的な queue 機能に精通していないと理解するのが難しいかもしれません。
Laravel Horizon は、あなたの Laravel で動力を供給されるRedis queuesのための美しいダッシュボードとコード駆動の設定を提供します。 Horizon を使用することで、 queue システムの主要な指標、例えば job のスループット、 runtime 、そして job の失敗を簡単にモニタリングすることができます。
Horizon を使用すると、すべての queue ワーカーの設定が single 、シンプルな設定ファイルに保存されます。アプリケーションのワーカー設定をバージョン管理されたファイルで定義することにより、アプリケーションの queue ワーカーを application の配布時に簡単にスケールまたは変更することが可能になります。
Installation
WARNING
Laravel Horizon は、あなたの queue connection を供給するためにRedis を使用することを必要とします。したがって、application の
config/queue.php
設定ファイルで queue 接続がredis
に設定されていることを確認する必要があります。
あなたはパッケージマネージャーの Composer を使って、あなたの project に Horizon をインストールすることができます:
composer require laravel/horizon
Horizon をインストールした後、horizon:install
の Artisan command を使用して、そのアセットを publish してください。
php artisan horizon:install
Configuration
Horizon の資産を公開した後、その primary 設定ファイルは config/horizon.php
に位置することになります。この設定ファイルでは application のための queue worker options を設定することが可能です。各設定オプションにはその目的の説明が含まれていますので、このファイルを十分に探索することを確認してください。
WARNING
Horizon は内部で
horizon
という名前の Redis connection を使用します。この Redis connection の名前は予約されており、database.php
の設定ファイルやhorizon.php
の設定ファイル内のuse
オプションの value として他の Redis connection に割り当てるべきではありません。
Environments
インストール後、まず詳しくなるべき primary Horizon 設定 option は、environments
設定 option です。この設定 option はあなたの application が稼働する環境の array であり、各環境の労働者 processoption を定義します。default では、このエントリにはproduction
とlocal
環境が含まれています。しかし、必要に応じてさらに環境を追加することができます:
'environments' => [
'production' => [
'supervisor-1' => [
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],
'local' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],
Horizon を開始すると、稼働中の application の environment に対する process の設定 options を使用します。通常、environment は APP_ENV
environment variableの value によって決定されます。例えば、default のlocal
Horizon environment は、3 つのワーカー process を起動し、各 queue に割り当てられたワーカー process の数を自動的に balance します。default のproduction
environment は最大 10 のワーカー process を開始し、各 queue に割り当てられたワーカー process の数を自動的に balance するように設定されています。
WARNING
horizon
設定ファイルのenvironments
部分には、 Horizon を実行する予定の各environmentのエントリが含まれていることを確認する必要があります。
Supervisors
Horizon の default 設定ファイルに記載されているように、各 environment は 1 つまたは複数の"supervisors"を含むことができます。 default で、この管理者はsupervisor-1
と定義されていますが、管理者の名前は自由に設定できます。各監督者は基本的に、ワーカープロセスのグループの"監視"を担当し、ワーカープロセスを queues 間でバランスをとる役割を果たしています。
あなたは新たな一群のワーカー process を定義し、その process が特定の environment で動作するようにしたい場合、追加の監視員を追加することができます。 異なるバランシング戦略を定義したり、あなたの application が使用する特定の queue に対してワーカー process の数を定義したい場合、これを行うことを選択するかもしれません。
メンテナンスモード
あなたの application がメンテナンスモードにある間、queue に入っている jobs は、 Horizon unless が監督者の force
option が true
と定義されている場合を除き、 Horizon の設定ファイル内で処理されません:
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'force' => true,
],
],
],
Default Values
Horizon の default 設定ファイルの中では、 defaults
設定 option に気づくでしょう。この設定 option は、application のスーパーバイザーの defaultvalues を指定します。default の values は、各環境のスーパーバイザー設定に merge され、スーパーバイザーを定義する際の不要な反復を避けます。
バランシング戦略
Laravel の default queue システムとは異なり、 Horizon では、simple
、auto
、false
の 3 つのワーカーバランシング戦略から選択できます。simple
戦略は、受信した jobs をワーカープロセス間で均等に分割します:
'balance' => 'simple',
auto
戦略は、設定ファイルの default で、 queue ごとのワーカープロセスの数をその queue の現在のワークロードに基づいて調整します。たとえば、あなたのnotifications
queue が 1,000 の未処理の jobs を抱えている一方で、あなたのrender
queue が空である場合、 Horizon はnotifications
queue により多くのワーカーを割り当てることで、 queue が空になるまで処理を行います。
auto
戦略を使用する場合、minProcesses
とmaxProcesses
の設定 options を定義して、 Horizon がスケールアップおよびダウンするための最小および最大のワーカープロセス数を制御できます。
'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto',
'autoScalingStrategy' => 'time',
'minProcesses' => 1,
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
'tries' => 3,
],
],
],
autoScalingStrategy
設定の value は、Horizon が合計の時間に基づいて queues により多くのワーカー processes を割り当てるか(time
ストラテジー)、または queue 上の jobs の合計数に基づいて割り当てるか(size
ストラテジー)を決定します。
balanceMaxShift
とbalanceCooldown
の設定 values は、 Horizon が労働者の需要にどれだけ早く対応するかを決定します。上記の例では、新しい process は最大で 3 秒ごとに 1 つ作成または破棄されます。これらの values は、application のニーズに基づいて必要に応じて調整することができます。
balance
option がfalse
に設定されている場合、default の Laravel の動作が使用され、queues が処理される順序は、あなたの設定でリストされている順序になります。
ダッシュボード Authorization
Horizon ダッシュボードは、/horizon
route 経由でアクセス可能です。 default では、このダッシュボードはlocal
environment でのみアクセス可能です。ただし、あなたのapp/Providers/HorizonServiceProvider.php
ファイル内には、authorization gateの定義があります。この authorization gate は、非ローカル environments での Horizon へのアクセスを制御します。このゲートは必要に応じて修正し、 Horizon インストールへのアクセスを制限することができます。
/**
* 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',
]);
});
}
代替の Authentication ストラテジー
Laravel は認証された user をゲートクロージャに自動的に注入することを忘れないでください。もしアプリケーションが IP 制限などの別の method によって Horizon のセキュリティを提供している場合、 Horizon users は "login" する必要がないかもしれません。したがって、 function (User $user)
クロージャの signature を function (User $user = null)
に変更して、 Laravel が authentication を要求しないようにする必要があります。
沈黙した Jobs
時折、あなたは自分の application やサードパーティのパッケージが送り出す特定の jobs を見たくない場合があるかもしれません。これらの jobs が"Completed jobs"リストのスペースを占めるのを防ぐ代わりに、これらをミュートにすることができます。始めるには、job の class 名を application のhorizon
設定ファイルのsilenced
設定 option に追加してください:
'silenced' => [
App\Jobs\ProcessPodcast::class,
],
あるいは、消音したい job は、Laravel\Horizon\Contracts\Silenced
インターフェースを実装することができます。もし job がこのインターフェースを実装している場合、それがsilenced
設定 array に存在しなくても自動的に消音されます。
use Laravel\Horizon\Contracts\Silenced;
class ProcessPodcast implements ShouldQueue, Silenced
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
// ...
}
Upgrading Horizon
新しいメジャーバージョンの Horizon へアップグレードする際には、アップグレードガイド を慎重に確認することが重要です。
Running Horizon
アプリケーションのconfig/horizon.php
設定ファイルでスーパーバイザーとワーカーを設定したら、horizon
Artisan command を使って Horizon を開始できます。この single command で現在の environment に設定されているすべてのワーカープロセスが開始されます:
php artisan horizon
あなたは Horizon process を一時停止させ、horizon:pause
やhorizon:continue
Artisan コマンドを使ってそれに processing jobs の続行を指示することができます。
php artisan horizon:pause
php artisan horizon:continue
あなたはまた、特定の Horizon supervisors を horizon:pause-supervisor
と horizon:continue-supervisor
Artisan コマンドを使って一時停止し、続けることもできます:
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1
horizon:status
の Artisan command を使用して、 Horizon process の現在の status を確認することができます:
php artisan horizon:status
あなたは horizon:terminate
の Artisan command を使用して、Horizonprocess を風格良く終了することができます。現在処理中のすべての jobs は完了し、その後 Horizon は実行を停止します。
php artisan horizon:terminate
Horizon のデプロイ
あなたが実際のアプリケーションサーバーに Horizon をデプロイする準備ができたら、php artisan horizon
command を監視し、予期せずに終了した場合に再起動する process モニターを設定する必要があります。心配しないで、下で process モニターのインストール方法を説明します。
アプリケーションの deployment process の間には、あなたは Horizon process に対して terminate を指示するべきで、それによってあなたの process モニターによって再起動され、あなたの code の変更を受け取るでしょう。
php artisan horizon:terminate
Supervisor のインストール
Supervisor は Linux オペレーティングシステムの process モニターで、horizon
process の実行が停止した場合に自動的に再起動します。Ubuntu に Supervisor をインストールするには、次の command を使用することができます。Ubuntu を使用していない場合でも、おそらくオペレーティングシステムのパッケージマネージャーを使用して Supervisor をインストールすることができます。
sudo apt-get install supervisor
NOTE
Supervisor の設定が大変そうなら、Laravel Forge の利用を検討してみてください。これにより、 Laravel プロジェクトの Supervisor のインストールと設定が自動的に行われます。
スーパーバイザー設定
スーパーバイザーの設定ファイルは通常、あなたのサーバーの/etc/supervisor/conf.d
ディレクトリ内に保存されます。このディレクトリ内で、どのようにプロセスを監視するかを指示する設定ファイルをいくつでも作成することができます。例えば、horizon
process を開始し、監視するhorizon.conf
ファイルを作成しましょう。
[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
の value が最も長く実行されていた job によって消費される秒数よりも多くなるように確認すべきです。そうでないと、Supervisor は job が処理を終える前に終了するかもしれません。
WARNING
上記の例は Ubuntu ベースのサーバーに有効ですが、Supervisor の設定ファイルの場所やファイル拡張子は他のサーバーのオペレーティングシステム間で異なる場合があります。詳細については、サーバーのドキュメンテーションを参照してください。
スーパーバイザーの起動
設定ファイルが作成されたら、次のコマンドを使用して Supervisor の設定を update し、監視されるプロセスを開始できます:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start horizon
NOTE
Supervisor の実行に関する詳細な情報は、Supervisor documentation をご覧ください。
Tags
Horizon は、mailables、 broadcast events 、 notifications 、そしてキューに入った event listeners を含む jobs に tags を割り当てることができます。実際、 Horizon は、 job に添付されている Eloquent models に依存して、ほとんどの jobs を賢く自動的にタグ付けします。例えば、以下の job を見てください:
<?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
のインスタンスを持つこの search が、id
の attribute が 1
で queue に入れられた場合、自動的に tagApp\Models\Video:1
が付けられます。これは、 Horizon が job のプロパティを Eloquent models を探すからです。もし Eloquent models が見つかった場合、 Horizon は、models の class 名と primary key を使用して、 job に賢く tag を付けます。
use App\Jobs\RenderVideo;
use App\Models\Video;
$video = Video::find(1);
RenderVideo::dispatch($video);
手動でタグ付け Jobs
もしあなたが、キューイング可能なオブジェクトの一つに手動で tags を定義したいと思うなら、 tags
method を class 上に定義することができます。
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];
}
}
手動でタグ付け Event Listeners
キューに入れられた event リスナーの tags を取得する際、 Horizon は自動的に event インスタンスを tags
method に渡し、あなたが event data を tags に追加できるようにします:
class SendRenderNotifications implements ShouldQueue
{
/**
* Get the tags that should be assigned to the listener.
*
* @return array<int, string>
*/
public function tags(VideoRendered $event): array
{
return ['video:'.$event->video->id];
}
}
Notifications
WARNING
Horizon を設定して Slack や SMS の notifications を送信する際、関連する notification channel の前提条件を確認する必要があります。
あなたの queues が長い待ち時間を持つ時に通知を受け取りたい場合は、Horizon::routeMailNotificationsTo
、Horizon::routeSlackNotificationsTo
、そしてHorizon::routeSmsNotificationsTo
メソッドを使うことができます。これらのメソッドは、あなたのアプリケーションの App\Providers\HorizonServiceProvider
の boot
method から呼び出すことができます。
/**
* Bootstrap any application services.
*/
public function boot(): void
{
parent::boot();
Horizon::routeSmsNotificationsTo('15556667777');
Horizon::routeMailNotificationsTo('example@example.com');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
}
Notification 待機時間閾値の設定
アプリケーションのconfig/horizon.php
設定ファイル内で、何秒が"長い待ち時間"とみなされるかを設定することができます。このファイル内のwaits
設定オプションにより、それぞれの connection / queue の組み合わせごとに長待ち時間の閾値を制御できます。未定義の connection / queue の組み合わせは、長い待ち時間の閾値が 60 秒に default 設定されます:
'waits' => [
'redis:critical' => 30,
'redis:default' => 60,
'redis:batch' => 120,
],
Metrics
Artisan command は、メトリックスダッシュボードを含み、これによりご自身の job と queue の待ち時間とスループットに関する情報が提供されます。このダッシュボードを充実させるためには、application のroutes/console.php
ファイルで、Horizon のsnapshot
Artisan command を5分ごとに実行するよう設定する必要があります。
use Illuminate\Support\Facades\Schedule;
Schedule::command('horizon:snapshot')->everyFiveMinutes();
Deleting Failed Jobs
もし失敗した job を delete したい場合は、horizon:forget
command を使用することができます。horizon:forget
command は、その唯一の引数として失敗した job の ID または UUID を受け入れます:
php artisan horizon:forget 5
Clearing Jobs From Queues
アプリケーションの default queue から全ての jobs を delete したい場合、horizon:clear
Artisan command を使用して行うことができます。
php artisan horizon:clear
特定の queue から delete jobs を行うためにqueue
オプションを提供することができます:
php artisan horizon:clear --queue=emails