如何使用 laravel 隊列?下面由laravel教程欄目給大家介紹一下使用 laravel 隊列的方法,以及使用隊列的場景,希望對大家有所幫助!
為什么 ?
首先,我們要知道為什么要使用隊列,不使用隊列會怎么樣!優(yōu)缺點如何
我們可以舉例 幾個簡單場景。
郵件發(fā)送
郵件發(fā)送一般會面臨哪些問題 ??
- 發(fā)送緩慢
- 發(fā)送失敗
- 發(fā)送頻率過高,被服務商拒絕 又或者 被進入垃圾箱
使用隊列的好處在與哪里
-
提高客戶端響應
當發(fā)送時,我們不要立即處理,而是丟給服務器,且隊列進行管理和調(diào)度。 你可以自定義選擇立即發(fā)送 或者 根據(jù)配置延遲發(fā)送
-
提高容錯能力
在發(fā)送過程中,或許我們可能會遇到,目標被拒絕。例如大多數(shù)人 會遇到給 admin@qq.comn 發(fā)送報錯 502 的場景。 那這種場景,那么這種場景,我們可以理解其為是一個事件,在郵件發(fā)送的過程中,我們可以 引發(fā)構(gòu)建出如下幾種事件
- 發(fā)送失敗
- 郵件記錄入庫
- 代碼異常
- 郵件發(fā)送成功回調(diào)
- 發(fā)送失敗重試
通過此郵件發(fā)送,可能會導致多個耗時任務的產(chǎn)生,那我們其實也可以構(gòu)建出多個 隊列服務 出來。每個隊列管理 自己的事情,很好的 解耦 他們
通過 Laravel 隊列 可以很好的進行設置 立即發(fā)送、延遲發(fā)送、重試發(fā)送
-
發(fā)送頻率可控
使用過批量發(fā)送的郵件的 開發(fā)者 必然會遇到一個問題,那便是,如果我們直接進行批量發(fā)送,即同一時間 進行大量的郵件發(fā)送。那么郵件服務商很可能會把我們的郵件給拒絕 或者 郵件進入垃圾箱,被識別為 廣告那么,這里便是用到了 延遲發(fā)送,我們可以根據(jù)當前隊列服務中,已知的 正在等待 投遞的郵件,合理的配置頻率,或者 切換郵件配置,來達到,頻率可控。
如設置 一個配置一分鐘之類發(fā)送10次,等等方案。 同樣,我們這里可以做到 配置、頻率控制、發(fā)送控制 解耦
其他
當然 我們還有很多種情況都會用到
如何使用 Laravel 隊列
這里只是列出,大概的使用方向,和如何更好的去使用。代碼可能跑不起起來,主要是理解 邏輯 我們這里 使用的是 redis 作為驅(qū)動
驅(qū)動設置為 Redis
>?.env QUEUE_CONNECTION=redis >?在?config/queue.php?中可以找到
快速創(chuàng)建隊列 和 投遞任務
#?創(chuàng)建?任務 php?artisan?make:job?ProcessPodcast
自動生成 app/Jobs/EmailJob.php
class?EmailJob?implements?ShouldQueue { ????use?Dispatchable,?InteractsWithQueue,?Queueable,?SerializesModels; ????protected?$data; ????/** ?????*?Create?a?new?job?instance. ?????* ?????*?@return?void ?????*/ ????public?function?__construct(array?$data) ????{ ????????$this->data?=?$data; ????} ????/** ?????*?Execute?the?job. ?????* ?????*?@return?void ?????*/ ????public?function?handle() ????{ ????????$service?=?new?EmailService(); ????????//?...?檢查當前可用?Mailer ????????//?這里你自定義就好了,這個方法中你可以根據(jù)你自己的配置,獲取到當前可用的配置 ????????$mailer?=?$service->getMailer(); ????????//?...?獲取當前要發(fā)送的數(shù)據(jù) ????????$data?=?$this->data; ???????? ????????$service->send($mailer,?$data); ????} }
一些常用操作
這些操作都能從 文檔中找到
調(diào)用 發(fā)送
#?延遲?2分鐘?發(fā)送 #?這里使用的是?Crontab?包?(不過?Laravel?自帶) EmailJob::dispatch()->delay(now()->addMinutes(2)); #?立即發(fā)送?(不會進入到隊列中) EmailJob::dispatchNow();
這里的隊列默認用的 是 defult 隊列,我們可以修改為指定隊列服務
public?function?__construct(array?$data) { ????#?使用?emailQueue ????$this->onQueue('emailQueue'); ????$this->data?=?$data; }
設置失敗情況下重試次數(shù)
#?重試?5?次 public?$tries?=?5;
設置超時時間
/** *?確定任務應該超時的時間 * *?@return?DateTime */ public?function?retryUntil() { ????return?now()->addMinutes(10); }
啟動我們的隊列
如果不配置 onQueue 的話,可以不帶 —queue 參數(shù)配置
php?artisan?queue:work?--queue=emailQueue
結(jié)合 Events 來解耦
Laravel Event 也是通過 隊列實現(xiàn)的
#?創(chuàng)建?Event php?artisan?make:event?FailEvent class?FailEvent { ????use?Dispatchable,?InteractsWithSockets,?SerializesModels; ????protected?$data; ????protected?$tag; ????/** ?????*?@param?array?$data?投遞的數(shù)據(jù) ?????*?@param?string?$tag?要操作的事情 ?????*/ ????public?function?__construct(array?$data,?string?$tag?=?'system') ????{ ????????$this->data?=?$data; ????????$this->tag?=?$tag; ????} } #?創(chuàng)建?listener? php?artisan?make:listener?FailListener class?FailListener { ????/** ????*?Handle?the?event. ????*? ????*?@param??object??$event ????*?@return?void ????*/ ????public?function?handle(FailEvent?$event) ????{ ????????$this->{$event->tag}($event->data); ????} ????/** ?????*?處理系統(tǒng)異常 ?????*?DateTime:?2021/12/3?11:02?上午 ?????*?@param?array?$data ?????*/ ????public?function?system(array?$data) ????{ ????} ????/** ????*?處理郵件異常 ????*?DateTime:?2021/12/3?11:02?上午 ????*/ ????public?function?email() ????{ ???? ????} } #?app/Providers/EventServiceProvider.php protected?$listen?=?[ ????FailEvent::class?=>?[ ????????FailListener::class, ????], ] #?投遞 event(new?FailEvent(['error'?=?'異常信息'],?'email'));
其他
其實,Laravel 大多數(shù)幫我實現(xiàn)了整個流程而已。可以嘗試自己使用 redis 來實現(xiàn)一個可控隊列。熟練是掌握 Redis 相關數(shù)據(jù)類型即可. 這里簡要列出 Redis 中,在以上模式中會用到的數(shù)據(jù)類型
-
List
使用 它可以完成 出棧 入棧的 隊列功能
-
Hash
使用他 可以用來存儲,序列化后的 Event 或者 Job ?__construct 傳入進去的數(shù)據(jù),盡量不要將整個 類 序列化進去
也可以實現(xiàn)存儲,Mailer 數(shù)據(jù)
-
Sorted Set
可以 設置時間為 Sorted Set 中的分數(shù),通過分數(shù)排序,找到我們最近要執(zhí)行的隊列任務
當然,Redis 的用法還有很多,滿足自己的需求即可。
世界上沒有完美的解決方案,只有最適合你自己的方案,在工作中遇到問題,盡量要學會舉一反三,合理的運用各種 工具,設計方案去實現(xiàn)。 代碼 只是最終一個縮影而已,最終的要學會理解,每個語言 每個框架,也只是一種方案的實現(xiàn),融會貫通才無敵 …
更多編程相關知識,請訪問:laravel!!