[ Laravel 5.8 文件 ] 官方擴充套件包 —— 佇列系統解決方案:Laravel Horizon
簡介
Horizon 為 Laravel 提供了基於 Redis 的、擁有美觀後臺的、程式碼驅動配置的佇列系統。Horizon 讓我們可以輕鬆監控佇列系統的關鍵指標,例如任務吞吐量、執行時間和失敗任務等。
所有的佇列程序配置都存放在一個單獨的簡單配置檔案中,這樣的話配置檔案就可以存放到原始碼控制以便團隊所有成員的協作。
安裝
注:由於 Horizon 使用了非同步程序訊號,所以 PHP 7.1+ 以上版本才可以使用。其次,你需要確保在 queue
配置檔案中將佇列驅動被設定為 redis
。
我們使用 Composer 安裝 Horizon 到 Laravel 專案:
composer require laravel/horizon
安裝完成後,使用 Artisan 命令 horizon:install
釋出資源:
php artisan horizon:install
還可以建立 failed_jobs
表用來儲存執行失敗的佇列任務:
php artisan queue:failed-table php artisan migrate
升級 Horizon
升級到最新版本的 Horizon 時,需要仔細閱讀 升級指南 。
此外,你還要重新發布 Horizon 資原始檔:
php artisan horizon:assets
配置
釋出好前端資源後,主配置檔案就會出現在 config/horizon.php
。在這個配置檔案中,你可以配置佇列程序選項以及每個包含目的描述的配置項,所以使用 Horizon 前務必瀏覽下這個配置檔案。
balance 配置項
Horizon 提供了三種負載均衡策略以供選擇: simple
、 auto
和 false
, simple
是預設策略,在程序之間平均分配進入任務:
'balance' => 'simple',
auto
策略基於隊列當前負載調整每個佇列的工作程序數量。例如,如果 notifications
佇列有 1000 個等待執行的任務而 render
佇列是空的,那麼 Horizon 將會為 notifications
佇列分配更多的工作程序直到佇列為空。
如果把 balance
選項設定為 false
,就會使用預設的 Laravel 行為,也就是按照配置檔案中的排列順序處理佇列。
任務裁剪
horizon
配置檔案允許你配置最近和執行失敗任務保留的時長(單位:分鐘),預設情況下,最近任務保留1個小時,執行失敗任務保留1周:
'trim' => [ 'recent' => 60, 'failed' => 10080, ],
後臺授權
我們可以通過 /horizon
訪問 Horizon 後臺:
預設情況下,你只能在 local
環境下訪問這個後臺。在 app/Providers/HorizonServiceProvider.php
檔案中,有一個 gate
方法,該授權 gate 用於控制非本地環境對 Horizon 的訪問。你可以按照需要編輯這個 gate
方法來限制使用者對 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, [ '[email protected]', ]); }); }
執行 Horizon
如果你已經在配置檔案 config/horizon.php
中配置過工作程序,就可以使用 Artisan 命令 horizon
來啟動 Horizon,該命令會啟動所有配置的工作程序:
php artisan horizon
你可以使用 Artisan 命令 horizon:pause
和 horizon:continue
來暫停或繼續處理佇列任務:
php artisan horizon:pause php artisan horizon:continue
你還可以使用 Artisan 命令 horizon:terminate
來優雅地終止 Horizon 主程序 —— Horizon 會在所有當前正在執行的任務全部完成後退出:
php artisan horizon:terminate
部署 Horizon
如果要將 Horizon 部署到線上伺服器,需要配置一個程序監控來監控 php artisan horizon
命令的執行並在異常退出的情況下重啟該程序。部署新程式碼到伺服器的時候,需要終止 Horizon 主程序以便通過配置的程序監控以最新程式碼重啟程序。如上所述,我們可以通過 Artisan 命令 horizon:terminate
優雅地終止 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 會基於附加到任務的 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; /** * The video instance. * * @var \App\Video */ public $video; /** * Create a new job instance. * * @param\App\Video$video * @return void */ public function __construct(Video $video) { $this->video = $video; } /** * Execute the job. * * @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 { /** * Get the tags that should be assigned to the job. * * @return array */ public function tags() { return ['render', 'video:'.$this->video->id]; } }
通知
注:在使用通知之前,需要通過 Composer 安裝 guzzlehttp/guzzle
依賴。在配置 Horizon 傳送簡訊通知前,還要回顧下 Nexmo 通知驅動的預備知識 。
如果你想要在某個佇列任務等待很長時間後被通知,可以使用 Horizon::routeMailNotificationsTo
、 Horizon::routeSlackNotificationsTo
以及 Horizon::routeSmsNotificationsTo
方法。你可以在 AppServiceProvider
中呼叫這些方法:
Horizon::routeMailNotificationsTo('[email protected]'); Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel'); Horizon::routeSmsNotificationsTo('15556667777');
配置通知等待時間下限
你可以在配置檔案 config/horizon.php
中通過修改 waits
配置項來配置每個連線/佇列上的等待時間下限(秒):
'waits' => [ 'redis:default' => 60, ],
監控
Horizon 提供了一個監控後臺檢視任務和佇列的等待時間和吞吐量資訊,為了獲取實時資訊,可以配置 Horizon 的 Artisan 命令 snapshot
通過應用的排程器每五分鐘執行一次:
/** * Define the application's command schedule. * * @param\Illuminate\Console\Scheduling\Schedule$schedule * @return void */ protected function schedule(Schedule $schedule) { $schedule->command('horizon:snapshot')->everyFiveMinutes(); }