Laravel隊列詳解

1.隊列的應(yīng)用場景:

PHP在異步編程上的短板是眾所周知的瞻润,這也是當年P(guān)HP能夠迅速火起來的一個重要特性喘垂,當然甜刻,這也是Nodejs能夠火起來的一個相反方向的重要特性(Nodejs的亮點就是高并發(fā)的處理性能,只是安全性嘛正勒,仁者見智了)得院,PHP為保持語言的簡單,設(shè)計之初不考慮多線程章贞,直至PHP7祥绞,有了TSRM這樣的多線程并發(fā)處理機制,PHP 默認依然不支持多線程鸭限,如果一定要使用多線程蜕径,還需要安裝 pthread 擴展。盡管并發(fā)處理這塊一致是PHP的短板败京,同時兜喻,大并發(fā)處理的相關(guān)技術(shù)在PHP領(lǐng)域好像也是小妾生的兒子般不受待見,但是并不代表需求中就不需要這些東西赡麦,于是乎就有了并發(fā)的另外一種替代方案朴皆,就是我們今天所要瞎掰的,隊列隧甚。

可見车荔,隊列就是為了在某種程度上替代多線程而設(shè)計的一種處理并發(fā)的方式,同時戚扳,也就具備天生的秉性:異步忧便!用于處理耗時的工作,比如一個流程走到一個地方帽借,要發(fā)送一封郵件通知珠增,那我不能讓整個程序等到郵件發(fā)完了再繼續(xù)下去,那我就把發(fā)郵件的工作丟到一個隊列中去砍艾,讓這個工作慢慢做蒂教,我繼續(xù)處理響應(yīng)的邏輯。整個過程其實也就這么回事脆荷,沒有很困難凝垛。

2.laravel中的隊列的實現(xiàn)

閑話不扯,現(xiàn)在有了laravel蜓谋,我們不用自己設(shè)計隊列的實現(xiàn)機制梦皮,我們來看看怎么用就好了。

1)首先桃焕,我們要先弄清楚幾個基本概念剑肯,我們先來想想,我們要把一項一項的工作任務(wù)放到隊列里观堂,最樸素的想法让网,我們會怎么做呀忧?我們是不是先得給任務(wù)起個名字,然后至少得給它一段執(zhí)行的代碼吧溃睹,然后再把這一個任務(wù)作為一個整體的數(shù)據(jù)結(jié)構(gòu)放到一個叫做隊列的數(shù)據(jù)結(jié)構(gòu)中去而账,那要把名字和執(zhí)行的代碼關(guān)聯(lián)起來,肯定是用鍵值對的方式最方便了丸凭,所以福扬,怎么做呢?最簡單就是用數(shù)組嘍惜犀,一個數(shù)組铛碑,然后中間一堆鍵值對,鍵名是任務(wù)名虽界,鍵值是任務(wù)的執(zhí)行代碼汽烦。但是數(shù)組有一個問題,數(shù)組的檢索是一個完了接一個莉御,我沒法控制它中間執(zhí)行的異步操作捌餐獭?但是它能夠模仿出這些操作模式礁叔,所以牍颈,在laravel中,就有了一個驅(qū)動名琅关,叫sync煮岁,同步嘛,用來做測試用的涣易。

2)但是画机,如果執(zhí)行代碼太大,然后任務(wù)太多新症,怎么辦步氏?都擺到數(shù)組里總是不合適吧?那我們是不是就得考慮把這些鍵值對給它放到數(shù)據(jù)庫里面去徒爹?嗯荚醒,不錯,這是一種好思路隆嗅,也有人這么做腌且,同樣的,laravel也提供數(shù)據(jù)庫做隊列的驅(qū)動榛瓮,和前面一樣,反正我的目的就是把任務(wù)讓他們排隊去巫击,只是一個一個塞到數(shù)據(jù)庫禀晓,然后一個一個取出來執(zhí)行精续。

3)然后,就會有人想到了粹懒,我干嘛不采用更專業(yè)的軟件來做這個事重付?比如redis?人家天生就是鍵值對處理的凫乖,而且和數(shù)據(jù)庫不通确垫,redis的數(shù)據(jù)是在內(nèi)存中的,這樣明顯速度就提上來了帽芽,我們會這么想删掀,laravel團隊也會這么想,于是有了redis驅(qū)動导街。

4)然后披泪,有人想到了這么多方法,自然就有人想專業(yè)提供這些服務(wù)的搬瑰,于是就有比如亞馬遜這樣的公司提供一系列的產(chǎn)品來支持款票,就有了SQS這些驅(qū)動,等等等等泽论。艾少。。翼悴。

其實說白了缚够,就是把任務(wù)的鍵名和鍵值儲存起來而已,儲存的媒介用什么都可以抄瓦,而所謂的隊列驅(qū)動潮瓶,就是把儲存在這些媒介中的任務(wù)代碼拿住來按照隊列的算法進行執(zhí)行的一種調(diào)配方式的一段代碼而已

3.講完了這些钙姊,我們來看看怎么實現(xiàn)

我們以redis為例毯辅,來看看laravel怎么做隊列的:

1)一上來沒說的,安裝redis驅(qū)動:composer require 'predis/predis ~1.0'

當然煞额,您得先有redis思恐,如果系統(tǒng)沒裝,apt-get一個膊毁,yum一個隨您啦胀莹。

2)接下來,要把任務(wù)放隊列婚温,我們得先做一個任務(wù)出來,我們寫個簡單的提交用戶數(shù)據(jù)的任務(wù)吧:

執(zhí)行: php artisan make:job StoreUser

3)執(zhí)行完上述命令描焰,在App下多一個job目錄出來,然后StoreUser就在里頭,然后我們就可以寫StoreUser的任務(wù)內(nèi)容了:

<?php

namespace App\Jobs;

use ...

class StoreUser implements ShouldQueue

{

? ? use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

? ? protected $user;

? ? public function __construct(User $user)

{

? ? ? ? $this->user=$user;

? ? }

? ? ? public function handle()

{

? ? ? ? $this->user->name="queue";

? ? ? ? $this->user->email="queue@text.com";

? ? ? ? $this->user->password="slcwd";

? ? ? ? $this->user->save();

? ? }

? ? public function fail()

{

? ? ? ? dd('發(fā)送失敗');

? ? }

}

上面這個任務(wù)很簡單荆秦,就是依賴注入一個User模型篱竭,然后在handle方法里面寫一個用戶數(shù)據(jù)處理的方法,最后儲存步绸,沒設(shè)么意義掺逼,我們只是演示而已。

其實瓤介,也可以不用注入模型吕喘,比如可以寫一個服務(wù),然后把服務(wù)注入進來刑桑,反正是個類就行氯质。

4)接下來,我們告訴框架漾月,要用哪個驅(qū)動病梢,到.env下面寫這兩句話:

QUEUE_CONNECTION=redis

REDIS_QUEUE=email

這兩個配置,是配置所謂的“鏈接名”和“隊列名”梁肿。

所謂鏈接蜓陌,就是我們要存儲的哪一個存儲介質(zhì),好比銀行吩蔑,

隊列名钮热,就是我們要使用哪一條隊列。

5)這樣烛芬,如果使用的是單隊列隧期,其他就啥都不用管了,這下隊列已經(jīng)可以用了赘娄。文章最后我們再來探討一個鏈接多個隊列的情況仆潮。

6)然后我們寫一個路由,一個控制器:

路由:Route::get('/mail','Mail\UserQueueController@queue');

控制器的方法代碼:

public function queue()

{

? ? $user=User::find(1);

? ? Test::dispatch($user)->delay(10);

}

這樣遣臼,我們就可以把任務(wù)分發(fā)給隊列了性置。

等等。揍堰。鹏浅。。屏歹。隐砸。嗯,好像我們還沒有開啟隊列蝙眶,接著季希。。。胖眷。武通。。珊搀。

7)開啟隊列:

命令行中輸入:php artisan queue:work,work和linsten有啥區(qū)別尾菇,自行看手冊嘍境析。有空行在那閃也暫時不管它,這代表隊列已經(jīng)開始工作了派诬,只是我們還沒有把我們的工作發(fā)到隊列上劳淆,

8)現(xiàn)在在瀏覽器中輸入路由地址,過個10秒到數(shù)據(jù)庫中看下默赂,1號Id的用戶數(shù)據(jù)就被修改了沛鸵。

以上就是一個簡單的隊列使用,下面缆八,我們來探討以下曲掰,如何在一個鏈接中使用多個隊列,這是laravel手冊最坑爹的地方奈辰,寫的不清不楚栏妖,我找了一段別人寫的,抄來大家自己琢磨就好:

這是一個必然需要考慮到的問題奖恰,我不可能將所有任務(wù)都放在一個叫default的隊列中吊趾,這樣不容易對隊列進行管理。要指定不同的隊列瑟啃,非常簡單论泛,在dispatch()后緊接著跟上onQueue()方法即可:

Demo::dispatch()->onQueue('emails');

不對啊,我好像沒有定義過這個叫 emails 的 queue蛹屿。嗯屁奏,自然需要做出一點改動,在queue.php配置文件中的redis配置queue從default改為{default}蜡峰,這樣做的效果就是隊列的名稱可以從運行的時候動態(tài)拿到了袁,而不是寫死的。

如果使用 Lumen 框架湿颅,那么直接這么寫會報錯:Call to a member function onQueue() on string载绿。原因在于 Lumen 的 Job 基類中并沒有使用Illuminate\Foundation\Bus\Dispatchable這個trait,而是直接使用Illuminate\Bus\Queueable中的onQueue()方法油航。

那么現(xiàn)在就很清楚了崭庸,我們的 Job 類使用了Illuminate\Bus\Queueable這個trait,所以需要在 Job 類上調(diào)用這個onQueue()方法。

$job =newXXXJob();dispatch($job->onQueue('queue-name'));

當我們在開啟隊列的時候:

php artisan queue:work --queue=emails

這里指定的隊列名 emails 和dispatch時指定的隊列名保持一致即可怕享。

好了执赡,這兩個關(guān)卡打通了,手冊后面的東西就沒什么難的了函筋,自個兒試一試吧沙合?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跌帐,隨后出現(xiàn)的幾起案子首懈,更是在濱河造成了極大的恐慌,老刑警劉巖谨敛,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件究履,死亡現(xiàn)場離奇詭異,居然都是意外死亡脸狸,警方通過查閱死者的電腦和手機最仑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炊甲,“玉大人泥彤,你說我怎么就攤上這事∶鄞校” “怎么了全景?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長牵囤。 經(jīng)常有香客問我爸黄,道長,這世上最難降的妖魔是什么揭鳞? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任炕贵,我火速辦了婚禮,結(jié)果婚禮上野崇,老公的妹妹穿的比我還像新娘称开。我一直安慰自己,他們只是感情好乓梨,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布鳖轰。 她就那樣靜靜地躺著,像睡著了一般扶镀。 火紅的嫁衣襯著肌膚如雪蕴侣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天臭觉,我揣著相機與錄音昆雀,去河邊找鬼辱志。 笑死,一個胖子當著我的面吹牛狞膘,可吹牛的內(nèi)容都是我干的揩懒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼挽封,長吁一口氣:“原來是場噩夢啊……” “哼已球!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起场仲,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤和悦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后渠缕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡褒繁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年亦鳞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棒坏。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡燕差,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坝冕,到底是詐尸還是另有隱情徒探,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布喂窟,位于F島的核電站测暗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏磨澡。R本人自食惡果不足惜碗啄,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稳摄。 院中可真熱鬧稚字,春花似錦、人聲如沸厦酬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仗阅。三九已至昌讲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間霹菊,已是汗流浹背剧蚣。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工支竹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸠按。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓礼搁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親目尖。 傳聞我的和親對象是個殘疾皇子馒吴,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

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