一,構(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ū)動程序需要以下依賴項:
?Amazon SQS:?aws/aws-sdk-php
?Beanstalkd:?pda/pheanstalk~3.0
?IronMQ:?iron-io/iron_mq~1.5
?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