Lumen -- 隊列

一,構(gòu)建

1. lumen利用Laravel的隊列組件為各種不同的隊列服務(wù)提供統(tǒng)一的API昌腰。隊列允許將耗時任務(wù)(例如發(fā)送電子郵件)的處理推遲到稍后的時間开伏,從而大大加快了對應(yīng)用程序的web請求。

lumen和laravel提供了數(shù)據(jù)庫遭商,Beanstalked, IronMQ, Amazon SQS, Redis, null, 和同步隊列驅(qū)動(供本地使用)的支持固灵。空隊列驅(qū)動程序只是丟棄隊列的作業(yè)劫流,因此它們永遠不會運行巫玻。

2. .env文件中的QUEUE_DRIVER選項決定了應(yīng)用程序?qū)⑹褂玫年犃序?qū)動。

例如:

QUEUE_DRIVER=redis

QUEUE_REDIS_CONNECTION=redis_queue

3. 為了使用數(shù)據(jù)庫隊列驅(qū)動程序祠汇,您需要一個數(shù)據(jù)庫表來保存作業(yè)大审。表架構(gòu)應(yīng)如下所示:

手冊

4. 其他隊列依賴

隊列驅(qū)動程序需要以下依賴項:

\bullet ?Amazon SQS:?aws/aws-sdk-php

\bullet ?Beanstalkd:?pda/pheanstalk~3.0

\bullet ?IronMQ:?iron-io/iron_mq~1.5

\bullet ?Redis:?predis/predis~1.0

二, 基本用法

1. 推送一個作業(yè)到隊列中

應(yīng)用程序的所有可排隊作業(yè)都存儲在 App\Jobs 目錄中座哩⊥椒觯基類 App\Job 可以作為其余任務(wù)的基類。

注意:如果您打算使用 Queue facade根穷,請務(wù)必取消注釋 bootstrap/app.php 文件中的 $app->withFacades() 調(diào)用姜骡。

2. 要將新作業(yè)推送到隊列中,請使用 Queue::push 方法:

Queue::push(newSendEmail($message));

你也可以使用閉包路由或控制器的 dispatch 方法:

$this->dispatch(newSendEmail($message));

3.?當(dāng)作業(yè)被隊列執(zhí)行時屿良,作業(yè)的句柄方法將被調(diào)用圈澈。您可以在句柄方法上鍵入提示您需要的任何依賴項,服務(wù)容器將自動注入它們:

手冊

4.?為作業(yè)(job)指定隊列(queue)/Tube

Queue::pushOn('emails',newSendEmail($message));

5. 將相同的負(fù)載(payload)傳遞給多個作業(yè)(job)

如果您需要將相同的數(shù)據(jù)傳遞給多個隊列作業(yè)(queue job)尘惧,您可以使用 Queue::bulk 方法:

Queue::bulk([newSendEmail($message),newAnotherCommand]);

6. 延遲作業(yè)的執(zhí)行

有時您可能希望延遲正在排隊的隊列作業(yè)的執(zhí)行康栈。例如,您可能希望注冊一個15 分鐘后將向客戶發(fā)送電子郵件的隊列作業(yè)。您可以使用 Queue::later 方法完成此操作:

$date=Carbon::now()->addMinutes(15);

Queue::later($date, newSendEmail($message));

在此示例中啥么,我們使用 Carbon 日期庫來指定我們希望分配給作業(yè)的延遲登舞。或者悬荣,您可以將希望延遲的秒數(shù)作為整數(shù)傳遞菠秒。

7. 隊列和 Eloquent 模型(Queues And Eloquent Models)

如果您的隊列作業(yè)在其構(gòu)造函數(shù)中接受 Eloquent Model,則只有模型的標(biāo)識符將被序列化到隊列中氯迂。當(dāng)實際處理作業(yè)時践叠,隊列系統(tǒng)會自動從數(shù)據(jù)庫中重新檢索完整的模型實例。這對您的應(yīng)用程序完全透明嚼蚀,并且可以防止序列化完整的 Eloquent 模型實例可能出現(xiàn)的問題禁灼。

8.?刪除已處理的隊列作業(yè)

處理完作業(yè)后,必須將其從隊列中刪除轿曙。如果在你的工作執(zhí)行過程中沒有拋出異常弄捕,這將自動完成。

如果您想手動刪除或釋放作業(yè)拳芙,Illuminate\Queue\InteractsWithQueue trait 提供對隊列任務(wù)釋放和刪除方法的訪問察藐。 release 方法接受一個值:您希望等待作業(yè)再次可用的秒數(shù)皮璧。

手冊

9. 將任務(wù)釋放回隊列

如果正在處理的任務(wù)發(fā)生了異常舟扎,它將自動釋放回隊列,以便再次嘗試悴务。該任務(wù)將繼續(xù)釋放睹限,直到應(yīng)用程序允許的最大嘗試次數(shù)。最大嘗試次數(shù)由---- Artisan任務(wù):queue:listen或queue:work 使用的tries開關(guān)定義

10. 檢查嘗試運行次數(shù)

如果正在處理的任務(wù)發(fā)生異常讯檐,它將自動釋放回隊列羡疗。您可以嘗試方法檢查運行任務(wù)的嘗試次數(shù):

if($this->attempts() > 3){

}

注意:您的任務(wù)/句柄必須引用Illuminate\Queue\InteractsWithQueue才能調(diào)用此方法

三,更多調(diào)度方法

從請求映射命令屬性

將HTTP請求變量映射到任務(wù)(jobs)中是非常常見的别洪。因此lumen提供了一些輔助方法叨恨,使其成為一種便捷的方式,而不是強制您為每個請求手動執(zhí)行此操作挖垛。讓我們看一下來自閉包路由和控制器方法的dispatchFrom 方法

$this->dispatchFrom('Command\Class\Name',$request);

此方法將檢查任務(wù)類的構(gòu)造函數(shù)痒钝,然后從HTTP請求(或任何其他ArrayAccess對象)中提取變量,以填充任務(wù)所需的構(gòu)造函數(shù)參數(shù)痢毒。因此送矩,如果我們的任務(wù)類在其構(gòu)造函數(shù)中接受firstName變量,任務(wù)總線將嘗試從HTTP請求中提取firstName參數(shù)哪替。

還可以將數(shù)組作為第三個參數(shù)傳遞給dispatchFrom方法栋荸。此數(shù)組將用于填充請求中不可用的任何構(gòu)造函數(shù)參數(shù):

$this->dispatchFrom('Command\Class\Name',$request,[

????'firstName'=>'Taylor',

]);

四,排隊閉包

注意:在對閉包進行排隊之前,需要添加jeremeamia/superclosure?(~2.0)到composer.json文件中

您還可以將閉包推到隊列上晌块。這對于需要排隊的快速簡單任務(wù)非常方便:

將閉包推到隊列上

Queue::push(function($job) use($id){

????Account::delete($id);

????$job->delete();

});

注意:不要通過使用指令使閉包隊列對象可用爱沟,請考慮傳遞主鍵并從隊列作業(yè)中重新提取相關(guān)模型。這通趁可以避免意外的序列化行為钥顽。

當(dāng)使用Iron.io推送隊列時,你應(yīng)該采取額外的預(yù)防措施排隊閉包靠汁。接收隊列消息的端點(end-point)應(yīng)該檢查token蜂大,以驗證請求實際上來自Iron.io。例如蝶怔,推送隊列的端點(end-point)應(yīng)該是:https://yourapp.com/queue/receive?token=SecretToken奶浦。然后,您可以在封送(marshalling)隊列請求之前檢查應(yīng)用程序中的秘密令牌(secret token)的值踢星。

五澳叉,運行隊列監(jiān)聽器

Lumen和Laravel一樣,包括一個Artisan任務(wù)沐悦,當(dāng)新作業(yè)被推到隊列中時成洗,該任務(wù)將運行新作業(yè)。您可以通過使用queue:listen運行此任務(wù)

1. 開啟隊列監(jiān)聽器

php artisan queue:listen

您還可以指定監(jiān)聽器應(yīng)使用的隊列連接:

php artisan queue:listen connection

請注意藏否,一旦此任務(wù)啟動瓶殃,它將繼續(xù)運行,直到手動停止副签。您可以使用進程監(jiān)視器(如Supervisor)來確保隊列監(jiān)聽器不會停止運行遥椿。

您可以將以逗號分隔的隊列連接列表傳遞給監(jiān)聽器作業(yè),以設(shè)置隊列優(yōu)先級:

php artisan queue:listen--queue=high,low

在本例中淆储,高連接(high-connection)上的作業(yè)將始終在從低連接(low-connection)轉(zhuǎn)移到作業(yè)之前進行處理冠场。

2.?指定作業(yè)超時參數(shù)

您還可以設(shè)置每個作業(yè)應(yīng)允許運行的時間長度(以秒為單位):

php artisan queue:listen--timeout=60

3. 指定隊列睡眠持續(xù)時間

此外,您可以指定在輪詢新作業(yè)之前等待的秒數(shù):

php artisan queue:listen--sleep=5

請注意本砰,只有當(dāng)隊列中沒有作業(yè)時碴裙,隊列才會“休眠”。如果有更多的作業(yè)可用点额,隊列將繼續(xù)工作而不“休眠”舔株。

4. 正在處理隊列上的第一個作業(yè)

要僅處理隊列上的第一個作業(yè),可以使用queue:work作業(yè)

php artisan queue:work

六咖楣,守護進程隊列工作程序

queue:work還包括一個--daemon選項督笆,用于強制queue worker在不重新啟動框架的情況下繼續(xù)處理作業(yè)。與queue:listen作業(yè)相比诱贿,這會顯著減少CPU使用量娃肿。

要在守護程序模式下啟動隊列工作程序咕缎,請使用--daemon標(biāo)志:

php artisan queue:work connection--daemon

php artisan queue:work connection--daemon--sleep=3

php artisan queue:work connection--daemon--sleep=3--tries=3

如您所見,queue:work作業(yè)支持queue:listen可用的大部分相同選項料扰。您可以使用php artisan help queue:work job查看所有可用選項凭豪。

1. 使用守護進程隊列工作程序部署

使用守護進程隊列工作程序部署應(yīng)用程序的最簡單方法是在部署開始時將應(yīng)用程序置于維護模式。這可以使用php artisan down作業(yè)來完成晒杈。一旦應(yīng)用程序處于維護模式嫂伞,Lumen和Laravel將不接受隊列外的任何新作業(yè),但將繼續(xù)處理現(xiàn)有作業(yè)拯钻。

重啟workers的最簡單方法是在部署腳本中包含以下作業(yè):

php artisan queue:restart

此作業(yè)將指示所有隊列在完成當(dāng)前作業(yè)的處理后重新啟動帖努。

注意:此作業(yè)依賴緩存系統(tǒng)來安排重新啟動。默認(rèn)情況下粪般,APCu不適用于CLI作業(yè)拼余。如果您正在使用APCu,請在APCu配置添加apc.enable_cli=1亩歹。

2. 為守護進程隊列工作程序編寫代碼

守護進程隊列工作程序在處理每個作業(yè)之前不會重新啟動框架匙监。因此,在工作完成之前小作,你應(yīng)該小心地釋放任何沉重的資源亭姥。例如,如果您正在使用GD庫進行圖像處理顾稀,那么在完成操作時达罗,應(yīng)該使用imagedestroy?釋放內(nèi)存。

類似地础拨,當(dāng)被長時間運行的守護程序使用時氮块,數(shù)據(jù)庫連接可能會斷開绍载。您可以使用DB::reconnect方法來確保有一個新的連接诡宗。

七,失敗作業(yè)

由于事情并不總是按計劃進行击儡,有時排隊的作業(yè)會失敗塔沃。Lumen和Laravel提供了一種方便的方法來指定作業(yè)的最大嘗試次數(shù)。作業(yè)超過此嘗試次數(shù)后阳谍,它將被插入failed_jobs表中蛀柴。

1. failed_jobs表應(yīng)具有如下模式:

Schema::create('failed_jobs',function(Blueprint$table)

{

????$table->increments('id');

????$table->text('connection');

????$table->text('queue');

? ? $table->text('payload');

????$table->timestamp('failed_at');

});

2. 您可以通過使用queue:listen作業(yè)上使用--tries開關(guān),指定作業(yè)的最大嘗試次數(shù):

php artisan queue:listen connection-name--tries=3

3. 如果要注冊隊列作業(yè)失敗時將調(diào)用的事件矫夯,可以使用Queue::failing方法鸽疾。這個事件是通過電子郵件或HipChat通知團隊的絕佳機會。

Queue::failing(function($connection,$job,$data){

?});

4. 您還可以直接在隊列作業(yè)類上定義失敗的方法训貌,以便在發(fā)生故障時執(zhí)行特定操作:

public function failed()

{

????// Called when the job is failing...

}

5. 重試失敗作業(yè)

要查看所有失敗作業(yè)制肮,你可以使用Artisan作業(yè):queue:failed

php artisan queue:failed

?queue:failed將列出作業(yè)ID冒窍、連接、隊列和失敗時間豺鼻。作業(yè)ID可用于重試失敗的作業(yè)综液。例如,要重試ID為5的失敗作業(yè)儒飒,應(yīng)發(fā)出以下作業(yè):

php artisan queue:retry 5

如果要刪除一個失敗隊列谬莹,可以使用queue:forget作業(yè):

php artisan queue:forget 5

要刪除所有的失敗隊列,可以使用queue:flush作業(yè):

php artisan queue:flush

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桩了,一起剝皮案震驚了整個濱河市附帽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌井誉,老刑警劉巖士葫,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異送悔,居然都是意外死亡慢显,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門欠啤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荚藻,“玉大人,你說我怎么就攤上這事洁段∮τ” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵祠丝,是天一觀的道長疾呻。 經(jīng)常有香客問我,道長写半,這世上最難降的妖魔是什么岸蜗? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮叠蝇,結(jié)果婚禮上璃岳,老公的妹妹穿的比我還像新娘。我一直安慰自己悔捶,他們只是感情好铃慷,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜕该,像睡著了一般犁柜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堂淡,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天馋缅,我揣著相機與錄音坛怪,去河邊找鬼。 笑死股囊,一個胖子當(dāng)著我的面吹牛袜匿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播稚疹,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼居灯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了内狗?” 一聲冷哼從身側(cè)響起怪嫌,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柳沙,沒想到半個月后岩灭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡赂鲤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年噪径,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片数初。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡找爱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泡孩,到底是詐尸還是另有隱情车摄,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布仑鸥,位于F島的核電站吮播,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏眼俊。R本人自食惡果不足惜意狠,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泵琳。 院中可真熱鬧摄职,春花似錦誊役、人聲如沸获列。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽击孩。三九已至,卻和暖如春鹏漆,著一層夾襖步出監(jiān)牢的瞬間巩梢,已是汗流浹背创泄。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留括蝠,地道東北人鞠抑。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像忌警,于是被迫代替她去往敵國和親搁拙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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