2018-08-06Laravel官方擴(kuò)展包——隊(duì)列系統(tǒng)解決方案:Laravel Horizon

簡(jiǎn)介

Horizon 為 Laravel 提供了基于 Redis 的、擁有美觀后臺(tái)的羡疗、代碼驅(qū)動(dòng)配置的隊(duì)列系統(tǒng)染服。Horizon 讓我們可以輕松監(jiān)控隊(duì)列系統(tǒng)的關(guān)鍵指標(biāo),例如任務(wù)吞吐量叨恨、運(yùn)行時(shí)間和失敗任務(wù)等柳刮。

所有的隊(duì)列進(jìn)程配置都存放在一個(gè)單獨(dú)的簡(jiǎn)單配置文件中,這樣的話(huà)配置文件就可以存放到源碼控制以便團(tuán)隊(duì)所有成員的協(xié)作痒钝。

安裝

注:由于 Horizon 使用了異步進(jìn)程信號(hào)秉颗,所以 PHP 7.1+ 以上版本才可以使用。

composer安裝Horizon命令:

composer require laravel/horizon

安裝完成后送矩,使用 Artisan 命令 vendor:publish 發(fā)布前端資源:

php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"
配置

發(fā)布好前端資源后蚕甥,主配置文件就會(huì)出現(xiàn)在 config/horizon.php。在這個(gè)配置文件中益愈,你可以配置隊(duì)列進(jìn)程選項(xiàng)以及每個(gè)包含目的描述的配置項(xiàng)梢灭,使用 Horizon 前可瀏覽下這個(gè)配置文件。

balance 配置項(xiàng)

Horizon 提供了三種負(fù)載均衡策略以供選擇:simple蒸其、auto 和 false敏释,simple 是默認(rèn)策略,在進(jìn)程之間平均分配進(jìn)入任務(wù):

'balance' => 'simple',

auto 策略基于隊(duì)列當(dāng)前負(fù)載調(diào)整每個(gè)隊(duì)列的工作進(jìn)程數(shù)量摸袁。例如钥顽,如果 notifications 隊(duì)列有 1000 個(gè)等待執(zhí)行的任務(wù)而 render 隊(duì)列是空的,那么 Horizon 將會(huì)為 notifications 隊(duì)列分配更多的工作進(jìn)程直到隊(duì)列為空靠汁。

如果把 balance 選項(xiàng)設(shè)置為 false蜂大,就會(huì)使用默認(rèn)的 Laravel 行為,也就是按照配置文件中的排列順序處理隊(duì)列蝶怔。

后臺(tái)認(rèn)證

我們可以通過(guò) /horizon 訪問(wèn) Horizon 后臺(tái):

image.png

默認(rèn)情況下奶浦,你只能在 local環(huán)境下訪問(wèn)這個(gè)后臺(tái)。如果想要為后臺(tái)定義更多的特定訪問(wèn)策略踢星,需要使用 Horizon:auth 方法澳叉。auth 方法接收一個(gè)返回truefalse 的回調(diào),從而決定用戶(hù)是否可以訪問(wèn) Horizon 后臺(tái)。通常成洗,我們會(huì)在 AppServiceProviderboot 方法中調(diào)用 Horizon:auth

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Laravel\Horizon\Horizon;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //用戶(hù)是否可以訪問(wèn) Horizon 后臺(tái)
        Horizon::auth(function ($request) {
            // return true / false;
        });
    }
}
運(yùn)行 Horizon

如果你已經(jīng)在配置文件 config/horizon.php 中配置過(guò)工作進(jìn)程五督,就可以使用 Artisan 命令 horizon 來(lái)啟動(dòng) Horizon,該命令會(huì)啟動(dòng)所有配置的工作進(jìn)程:

php artisan horizon

使用 Artisan 命令 horizon:pausehorizon:continue 來(lái)暫推垦辏或繼續(xù)處理隊(duì)列任務(wù):

php artisan horizon:pause

php artisan horizon:continue

還可以使用 Artisan 命令 horizon:terminate 來(lái)優(yōu)雅地終止 Horizon 主進(jìn)程 —— Horizon 會(huì)在所有當(dāng)前正在執(zhí)行的任務(wù)全部完成后退出:

php artisan horizon:terminate
部署 Horizon

如果要將 Horizon 部署到線上服務(wù)器充包,需要配置一個(gè)進(jìn)程監(jiān)控來(lái)監(jiān)控 php artisan horizon 命令的運(yùn)行并在異常退出的情況下重啟該進(jìn)程。部署新代碼到服務(wù)器的時(shí)候遥椿,需要終止 Horizon 主進(jìn)程以便通過(guò)配置的進(jìn)程監(jiān)控以最新代碼重啟進(jìn)程基矮。如上所述,我們可以通過(guò) Artisan 命令 horizon:terminate 優(yōu)雅地終止 Horizon 主進(jìn)修壕。

Supervisor 配置

如果你在使用 Supervisor 進(jìn)程監(jiān)控來(lái)管理 horizon 進(jìn)程愈捅,配置例子(按照自己的實(shí)際情況修改相應(yīng)的目錄信息):

[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 ForgeForge 提供了 PHP 7+ 版本的服務(wù)器慈鸠,并且擁有運(yùn)行最新版 Laravel 應(yīng)用所需的所有軟件工具集。

標(biāo)簽

Horizon 允許分配"標(biāo)簽"到任務(wù)灌具,包括郵件青团、事件廣播、通知以及隊(duì)列事件監(jiān)聽(tīng)器等咖楣。實(shí)際上督笆,Horizon 會(huì)基于附加到任務(wù)的 Eloquent 模型為大部分任務(wù)以智能的方式自動(dòng)打上標(biāo)簽。例如诱贿,我們來(lái)看看下面這個(gè)例子:

<?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()
    {
        //
    }
}

如果任務(wù)被推送到隊(duì)列時(shí)附帶了一個(gè) id1App\Video 實(shí)例娃肿,它將會(huì)自動(dòng)打上 App\Video:1 的標(biāo)簽,這是因?yàn)?Horizon 會(huì)檢查隊(duì)列任務(wù)屬性中的 Eloquent 模型珠十,如果 Eloquent 模型被找到料扰,Horizon 就會(huì)使用模型類(lèi)名和主鍵為任務(wù)智能地打上標(biāo)簽:

$video = App\Video::find(1);

App\Jobs\RenderVideo::dispatch($video);
手動(dòng)打標(biāo)簽

如果你想要手動(dòng)定義某個(gè)隊(duì)列對(duì)象的標(biāo)簽,可以在該類(lèi)中定義一個(gè) 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];
    }
}
通知

注:在使用通知之前焙蹭,需要通過(guò) Composer 安裝 guzzlehttp/guzzle 依賴(lài)晒杈。在配置 Horizon 發(fā)送短信通知前,還要回顧下 Nexmo 通知驅(qū)動(dòng)的預(yù)備知識(shí)孔厉。

如果你想要在某個(gè)隊(duì)列任務(wù)等待很長(zhǎng)時(shí)間后被通知拯钻,可以使用 Horizon::routeMailNotificationsToHorizon::routeSlackNotificationsTo 以及 Horizon::routeSmsNotificationsTo 方法撰豺。你可以在 AppServiceProvider 中調(diào)用這些方法:

Horizon::routeMailNotificationsTo('example@example.com');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
Horizon::routeSmsNotificationsTo('15556667777');
配置通知等待時(shí)間下限

你可以在配置文件 config/horizon.php 中通過(guò)修改 waits 配置項(xiàng)來(lái)配置每個(gè)連接/隊(duì)列上的等待時(shí)間下限(秒):

'waits' => [
    'redis:default' => 60,
],
監(jiān)控

Horizon 提供了一個(gè)監(jiān)控后臺(tái)查看任務(wù)和隊(duì)列的等待時(shí)間和吞吐量信息粪般,為了獲取實(shí)時(shí)信息,可以配置 HorizonArtisan 命令 snapshot 通過(guò)應(yīng)用的調(diào)度器每五分鐘運(yùn)行一次:

/**
 * Define the application's command schedule.
 *
 * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
 * @return void
 */
protected function schedule(Schedule $schedule)
{
    $schedule->command('horizon:snapshot')->everyFiveMinutes();
}

出處

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末污桦,一起剝皮案震驚了整個(gè)濱河市亩歹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖捆憎,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舅柜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡躲惰,警方通過(guò)查閱死者的電腦和手機(jī)致份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)础拨,“玉大人氮块,你說(shuō)我怎么就攤上這事」钭冢” “怎么了滔蝉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)塔沃。 經(jīng)常有香客問(wèn)我蝠引,道長(zhǎng),這世上最難降的妖魔是什么蛀柴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任螃概,我火速辦了婚禮,結(jié)果婚禮上鸽疾,老公的妹妹穿的比我還像新娘吊洼。我一直安慰自己,他們只是感情好制肮,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布冒窍。 她就那樣靜靜地躺著,像睡著了一般豺鼻。 火紅的嫁衣襯著肌膚如雪综液。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,792評(píng)論 1 290
  • 那天拘领,我揣著相機(jī)與錄音意乓,去河邊找鬼。 笑死约素,一個(gè)胖子當(dāng)著我的面吹牛届良,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播圣猎,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼士葫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了送悔?” 一聲冷哼從身側(cè)響起慢显,我...
    開(kāi)封第一講書(shū)人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤爪模,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荚藻,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體屋灌,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年应狱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了共郭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疾呻,死狀恐怖除嘹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岸蜗,我是刑警寧澤尉咕,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站璃岳,受9級(jí)特大地震影響年缎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铃慷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一晦款、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枚冗,春花似錦、人聲如沸蛇损。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)淤齐。三九已至股囊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間更啄,已是汗流浹背稚疹。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祭务,地道東北人内狗。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像义锥,于是被迫代替她去往敵國(guó)和親柳沙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Laravel 學(xué)習(xí)交流 QQ 群:375462817 本文檔前言Laravel 文檔寫(xiě)的很好拌倍,只是新手看起來(lái)會(huì)有...
    Leonzai閱讀 7,835評(píng)論 2 12
  • 原文鏈接 必備品 文檔:Documentation API:API Reference 視頻:Laracasts ...
    layjoy閱讀 8,605評(píng)論 0 121
  • 隊(duì)列 簡(jiǎn)介 laravel 的隊(duì)列服務(wù)對(duì)各種不同的后臺(tái)隊(duì)列服務(wù)提供了統(tǒng)一的 API赂鲤。隊(duì)列允許你延遲執(zhí)行消耗時(shí)間的任...
    Dearmadman閱讀 20,736評(píng)論 7 26
  • 有多久沒(méi)有讀完一本書(shū)了噪径。記得小時(shí)候爸爸每年都會(huì)帶我去書(shū)市,買(mǎi)一大堆書(shū)回來(lái)数初,還會(huì)買(mǎi)些好吃的找爱,到家后和媽媽一起吃頓大餐...
    靜聽(tīng)心曲閱讀 190評(píng)論 0 0
  • 睡到自然醒,舒服至極泡孩。 游玩车摄,聊天,學(xué)習(xí)珍德。 好像感覺(jué)沒(méi)有那么振奮去過(guò)這一天练般,很自在很舒適。沒(méi)有覺(jué)得必須去做锈候,自然想...
    遠(yuǎn)山近水_閱讀 79評(píng)論 0 0