在laravel中,隊列是一種操作受限制的線性表,它只允許在表的前端(隊頭)進行刪除操作,而在表的后端(隊尾)進行插入操作;通過隊列,開發(fā)者可以將耗時任務的處理往后推延,進而可以極大地提升web請求響應速度。
本教程操作環(huán)境:windows7系統(tǒng)、Laravel6版、Dell G3電腦。
laravel中隊列的使用
1、什么是隊列
隊列是一種操作受限制的線性表,特殊之處在于它只允許在表的前端進行刪除操作,而在表的后端進行插入操作。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。
通過隊列,你可以將耗時任務 (如發(fā)送電子郵件) 的處理往后推延。延遲這些耗時的任務可以極大地提升 web 請求響應速度。
2、優(yōu)點
-
解耦:消息隊列可以對系統(tǒng)進行解耦,提高響應速度,系統(tǒng)功能向內(nèi)聚合,對外開放;
-
異步:消息隊列可以對系統(tǒng)異步功能進行剝離,減少功能耦合,提供開發(fā)效率;
-
削峰:消息隊列可以削峰限流,確保下游消費者穩(wěn)定運行;
3、配置
隊列配置文件存儲在 config/queue.php 中。 在這個文件中,你可以找到框架中包含的每個隊列驅(qū)動程序的連接配置,其中包括數(shù)據(jù)庫,Beanstalkd,Amazon SQS,redis,和一個同步驅(qū)動程序(sync-供本地使用)。
這里使用 Redis 作為驅(qū)動,需要安裝好 Redis 以及 相關(guān)擴展。
4、任務
我們需要把一些東西放入隊列中,我們可以稱之為任務。Laravel 框架中創(chuàng)建任務給我們提供了以下命令:
php?artisan?make:job?TestJob
TestJob.php
namespace?AppJobs;use?IlluminateBusQueueable;use?IlluminateContractsQueueShouldBeUnique;use?IlluminateContractsQueueShouldQueue;use?IlluminateFoundationBusDispatchable;use?IlluminateQueueInteractsWithQueue;use?IlluminateQueueSerializesModels;use?IlluminateSupportFacadesDB;use?SymfonyPolyfillIntlIdnInfo;class?TestJob?implements?ShouldQueue{ ????use?Dispatchable,?InteractsWithQueue,?Queueable,?SerializesModels; ????/** ?????*?Create?a?new?job?instance. ?????* ?????*?@return?void ?????*/ ????public?function?__construct() ????{ ????????// ????} ????/** ?????*?Execute?the?job. ?????* ?????*?@return?void ?????*/ ????public?function?handle() ????{//????????Log::info('hhh'); ????????DB::connection('test') ????????????->table('master') ????????????->insert([ ????????????????'name'=>'小白', ????????????????'email'=>'123@qq.com' ????????????]); ????}}
5、分發(fā)
一旦編寫了任務類,就可以使用任務本身的 dispatch 方法來分派它。傳遞給 dispatch 方法的參數(shù)將被傳遞給任務的構(gòu)造函數(shù)。
onQueue: ? ? ? ? ? 指定隊列;
onConnection: ? 指定連接;
delay: ? ? ? ? ?延遲隊列;
dispatchNow: ? ? ? ?同步調(diào)度;
#在路由中簡單調(diào)用 Route::get('queue',function(){ ????????AppJobsTestJob::dispatch(); //????????AppJobsTestJob::dispatch()->onQueue('qq'); ????});
運行兩次該路由可以看到生成一個名為qq的隊列,后面我們對隊列進行消費
6、隊列消費
Laravel 有一個隊列處理器對新推入隊列的任務進行處理。通過 Artisan 命令 queue:work 來啟動隊列處理器。需要注意的是,一旦 queue:work 命令啟動,將一直保持運行,直到它被手動停止或你關(guān)閉你的終端:
php artisan queue:work
php artisan queue:work –once ?添加參數(shù),消費指定隊列
#消費qq隊列 php?artisan?queue:work?--queue=qq
可以看到數(shù)據(jù)庫中新增了兩條數(shù)據(jù),并且redis中數(shù)據(jù)被消費
我們再次執(zhí)行路由
7、事件隊列
隊列通常是用來處理延遲任務,事件是業(yè)務邏輯處理。Laravel 中的 事件 觸發(fā)器分發(fā)至隊列中進行異步業(yè)務處理,那么這樣之后可以快速做出響應而不用實時等待執(zhí)行結(jié)果之后才能給使用者做出提示消息。
如果需要把事件中的業(yè)務存放到隊列中去,我們并不需要重新進行隊列的分發(fā),直接在對應的監(jiān)聽器中實現(xiàn) IlluminateContractsQueueShouldQueue 接口即可。
創(chuàng)建事件和監(jiān)聽器
php?artisan?make:event?TestEvent php?artisan?make:listener?TestListener
在appprovidersEventServiceProvider.php中注冊
TestListener.php
namespace?AppListeners; use?IlluminateContractsQueueShouldQueue; use?IlluminateQueueInteractsWithQueue; use?IlluminateSupportFacadesDB; class?TestListener?implements?ShouldQueue { ????/** ?????*?Create?the?event?listener. ?????* ?????*?@return?void ?????*/ ????public?function?__construct() ????{ ????????// ????} ????/** ?????*?Handle?the?event. ?????* ?????*?@param??object??$event ?????*?@return?void ?????*/ ????public?function?handle() ????{ ????????DB::connection('test') ????????????->table('master') ????????????->insert([ ????????????????'name'=>'小黑', ????????????????'email'=>'234@qq.com' ????????????]); ????} }
修改路由
Route::get('queue',function(){ ????????//AppJobsTestJob::dispatch(); ????????//指定隊列名稱 ????????//AppJobsTestJob::dispatch()->onQueue('qq'); ????????return?event(new?AppEventsTestEvent()); ????});
運行路由
消費隊列
php?artisan?queue:work
【相關(guān)推薦:laravel視頻教程】