# Laravel 隊列監控面板 - Horizon
- [介紹](#introduction)
- [安裝](#installation)
- [配置](#configuration)
- [儀表盤授權](#dashboard-authentication)
- [運行 Horizon](#running-horizon)
- [部署 Horizon](#deploying-horizon)
- [標簽](#tags)
- [通知](#notifications)
- [Metrics](#metrics)
<a name="introduction"></a>
## 介紹
Horizon 為 Laravel 官方出品的 Redis 隊列提供了一個可以通過代碼進行配置、并且非常漂亮的儀表盤,并且能夠輕松監控隊列的任務吞吐量、執行時間以及任務失敗情況等關鍵指標。
隊列執行者的所有配置項都存放在一個簡單的配置文件中,所以團隊可以通過版本控制進行協作維護。
<a name="installation"></a>
## 安裝
> {note} 由于 Horizon 中使用了異步處理信號,所以需要 PHP 7.1+
可以使用 Composer 將 Horizon 安裝進你的 Laravel 項目:
composer require laravel/horizon
安裝完成后,使用 `vendor:publish` Artisan 命令發布相關文件:
php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"
<a name="configuration"></a>
### 配置
發布相關文件過程中,Horizon 的主要配置文件會被放置到 `config/horizon.php`,我們可以通過此文件配置隊列執行者的所有配置項,此文件中的每個配置項都包含一份完整的使用說明,所以推薦認真閱讀此文件。
#### 負載均衡配置
Horizon 有三種負載均衡策略:`simple`、`auto`、 和 `false`,默認策略是 `simple`,會將接收到的任務均分給隊列進程:
'balance' => 'simple',
策略 `auto` 會根據每個隊列的壓力自動調整其執行者進程數目,例如:如果 `notifications` 有 1000 個待執行的任務,但是你的 `render` 隊列是空的,Horizon 會分派更多執行者進程給 `notifications` 隊列,直到隊列任務全部執行完畢(即隊列為空)。當配置項 `balance` 設置為 `false` 時,Horizon 的執行策略與 Laravel 默認行為一致,及根據隊列在配置文件中配置的順序處理隊列任務。
<a name="dashboard-authentication"></a>
### 儀表盤權限驗證
Horizon 儀表盤的路由是 `/horizon` ,默認只能在 `local` 環境中訪問儀表盤。我們可以使用 `Horizon::auth` 函數定義更具體的訪問策略。`auth` 函數能夠接受一個回調函數,此回調函數需要返回 `true` 或 `false` ,從而確認當前用戶是否有權限訪問 Horizon 儀表盤:
Horizon::auth(function ($request) {
// return true / false;
});
<a name="running-horizon"></a>
## 運行 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 當前執行中的任務會被正常完成,然后 Horizon 執行結束:
php artisan horizon:terminate
<a name="deploying-horizon"></a>
### 部署 Horizon
生產環境中,我們需要配置一個進程管理工具來監控 `php artisan horizon` 命令的執行,以便在其意外退出時自動重啟。當服務器部署新代碼時,需要終止當前 Horizon 主進程,然后通過進程管理工具來重啟,從而使用最新的代碼。
使用 Artisan 命令 `horizon:terminate` 來正常停止系統中的 Horizon 主進程,此命令執行時,Horizon 當前執行中的任務會被正常完成,然后 Horizon 執行結束:
php artisan horizon:terminate
#### Supervisor 配置
可以使用進程管理工具 Supervisor 來管理 `horizon` 進程,下面配置文件就已夠用:
[program:horizon]
process_name=%(program_name)
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
> {tip} 如果你不喜歡自己維護服務器,可以考慮使用 [Laravel Forge](https://forge.laravel.com) ,Forge 提供了運行一個帶有 Horizon 的現代、強大的 Laravel 應用所需的 PHP7+ 以及其他所有環境。
<a name="tags"></a>
## 標簽
Horizon 允許我們給隊列任務打上一系列標簽,包括 mailables、事件廣播、通知以及隊列中的時間偵聽器,事實上,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()
{
//
}
}
如果此任務放入隊列時攜帶了一個 `App\Video` 實例,此實例的 `id` 為 `1`,這個任務會接收到一個 `App\Video:1` 標簽,這是因為 Horizon 會檢查任務的所有屬性是否攜帶 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];
}
}
<a name="notifications"></a>
## 通知
> **Note:** 使用通知之前,需要將 Composer 包 `guzzlehttp/guzzle` 安裝到目標項目,如果配置 Horizon 發送短信通知,也要注意閱讀[Nexmo 通知驅動的依賴條件](https://laravel.com/docs/5.4/notifications#sms-notifications)。
如果需要在隊列等待時間過長時發起通知,可以在應用的 `AppServiceProvider` 中調用 `Horizon::routeSlackNotificationsTo` 和 `Horizon::routeSmsNotificationsTo` 函數:
Horizon::routeSlackNotificationsTo('slack-webhook-url');
Horizon::routeSmsNotificationsTo('15556667777');
#### 配置等待時間過長通知的閾值
可以在 `config/horizon.php` 中配置等待時間過長具體秒數,配置項 `waits` 可以針對每個 鏈接/隊列 配置閾值:
'waits' => [
'redis:default' => 60,
],
<a name="metrics"></a>
## Metrics
Horizon 包含一個 metrics 儀表盤,它可以提供任務和隊列等待時間和吞吐量信息,為了填充此儀表盤,需要使用應用的 [scheduler](/docs/{{version}}/scheduling) 每五分鐘運行一次 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();
}
## 譯者署名
| 用戶名 | 頭像 | 職能 | 簽名 |
|---|---|---|---|
| [@zhwei](https://github.com/zhwei) | <img class="avatar-66 rm-style" src="https://avatars3.githubusercontent.com/u/1446459?v=3&s=100"> | 翻譯 | [歡迎加入蛋殼公寓](http://www.dankegongyu.com/about/join.html?from=laravel-doc-55) |
---
> {note} 歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動共創開源社區。
>
> 轉載請注明:本文檔由 Laravel China 社區 [laravel-china.org](https://laravel-china.org) 組織翻譯,詳見 [翻譯召集帖](https://laravel-china.org/topics/5756/laravel-55-document-translation-call-come-and-join-the-translation)。
>
> 文檔永久地址: https://d.laravel-china.org
- 說明
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- HomeStead
- Valet
- 核心架構
- 請求周期
- 服務容器
- 服務提供者
- 門面(Facades)
- Contracts
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- 重定向
- Session
- 表單驗證
- 錯誤與日志
- 前端開發
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- API認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- API 資源
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Horizon
- Passport OAuth 認證
- Scout 全文搜索
- Socialite 社交化登錄
- 交流說明