聊聊 Laravel 的隊列機制,了解一下隊列的使用場景

如何使用 laravel 隊列?下面由laravel教程欄目給大家介紹一下使用 laravel 隊列的方法,以及使用隊列的場景,希望對大家有所幫助!

聊聊 Laravel 的隊列機制,了解一下隊列的使用場景

為什么 ?

首先,我們要知道為什么要使用隊列,不使用隊列會怎么樣!優缺點如何

我們可以舉例 幾個簡單場景。

郵件發送

郵件發送一般會面臨哪些問題 ??

  • 發送緩慢
  • 發送失敗
  • 發送頻率過高,被服務商拒絕 又或者 被進入垃圾箱

使用隊列的好處在與哪里

  • 提高客戶端響應

    當發送時,我們不要立即處理,而是丟給服務器,且隊列進行管理和調度。 你可以自定義選擇立即發送 或者 根據配置延遲發送

  • 提高容錯能力

    在發送過程中,或許我們可能會遇到,目標被拒絕。例如大多數人 會遇到給 admin@qq.comn 發送報錯 502 的場景。 那這種場景,那么這種場景,我們可以理解其為是一個事件,在郵件發送的過程中,我們可以 引發構建出如下幾種事件

    • 發送失敗
    • 郵件記錄入庫
    • 代碼異常
    • 郵件發送成功回調
    • 發送失敗重試

    通過此郵件發送,可能會導致多個耗時任務的產生,那我們其實也可以構建出多個 隊列服務 出來。每個隊列管理 自己的事情,很好的 解耦 他們

    通過 Laravel 隊列 可以很好的進行設置 立即發送延遲發送重試發送

  • 發送頻率可控

    使用過批量發送的郵件的 開發者 必然會遇到一個問題,那便是,如果我們直接進行批量發送,即同一時間 進行大量的郵件發送。那么郵件服務商很可能會把我們的郵件給拒絕 或者 郵件進入垃圾箱,被識別為 廣告那么,這里便是用到了 延遲發送,我們可以根據當前隊列服務中,已知的 正在等待 投遞的郵件,合理的配置頻率,或者 切換郵件配置,來達到,頻率可控。

    如設置 一個配置一分鐘之類發送10次,等等方案。 同樣,我們這里可以做到 配置、頻率控制、發送控制 解耦

其他

當然 我們還有很多種情況都會用到

  • 服務器端下載 excel
  • 服務器端異步多任務處理 大數據
  • 錯誤消息處理

如何使用 Laravel 隊列

這里只是列出,大概的使用方向,和如何更好的去使用。代碼可能跑不起起來,主要是理解 邏輯 我們這里 使用的是 redis 作為驅動

驅動設置為 Redis

>?.env QUEUE_CONNECTION=redis >?在?config/queue.php?中可以找到

快速創建隊列 和 投遞任務

#?創建?任務 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 ????????//?這里你自定義就好了,這個方法中你可以根據你自己的配置,獲取到當前可用的配置 ????????$mailer?=?$service->getMailer();  ????????//?...?獲取當前要發送的數據 ????????$data?=?$this->data; ???????? ????????$service->send($mailer,?$data); ????} }

一些常用操作

這些操作都能從 文檔中找到

調用 發送

#?延遲?2分鐘?發送 #?這里使用的是?Crontab?包?(不過?Laravel?自帶) EmailJob::dispatch()->delay(now()->addMinutes(2));  #?立即發送?(不會進入到隊列中) EmailJob::dispatchNow();

這里的隊列默認用的 是 defult 隊列,我們可以修改為指定隊列服務

public?function?__construct(array?$data) { ????#?使用?emailQueue ????$this->onQueue('emailQueue'); ????$this->data?=?$data; }

設置失敗情況下重試次數

#?重試?5?次 public?$tries?=?5;

設置超時時間

/** *?確定任務應該超時的時間 * *?@return?DateTime */ public?function?retryUntil() { ????return?now()->addMinutes(10); }

啟動我們的隊列

如果不配置 onQueue 的話,可以不帶 —queue 參數配置

php?artisan?queue:work?--queue=emailQueue

結合 Events 來解耦

Laravel Event 也是通過 隊列實現的

#?創建?Event php?artisan?make:event?FailEvent  class?FailEvent { ????use?Dispatchable,?InteractsWithSockets,?SerializesModels;  ????protected?$data; ????protected?$tag;  ????/** ?????*?@param?array?$data?投遞的數據 ?????*?@param?string?$tag?要操作的事情 ?????*/ ????public?function?__construct(array?$data,?string?$tag?=?'system') ????{ ????????$this->data?=?$data; ????????$this->tag?=?$tag; ????} }  #?創建?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); ????}  ????/** ?????*?處理系統異常 ?????*?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 大多數幫我實現了整個流程而已。可以嘗試自己使用 redis 來實現一個可控隊列。熟練是掌握 Redis 相關數據類型即可. 這里簡要列出 Redis 中,在以上模式中會用到的數據類型

  • List

    使用 它可以完成 出 入棧的 隊列功能

  • Hash

    使用他 可以用來存儲,序列化后的 Event 或者 Job ?__construct 傳入進去的數據,盡量不要將整個 類 序列化進去

    也可以實現存儲,Mailer 數據

  • Sorted Set

    可以 設置時間為 Sorted Set 中的分數,通過分數排序,找到我們最近要執行的隊列任務

當然,Redis 的用法還有很多,滿足自己的需求即可。

世界上沒有完美的解決方案,只有最適合你自己的方案,在工作中遇到問題,盡量要學會舉一反三,合理的運用各種 工具,設計方案去實現。 代碼 只是最終一個縮影而已,最終的要學會理解,每個語言 每個框架,也只是一種方案的實現,融會貫通才無敵 …

更多編程相關知識,請訪問:laravel!!

? 版權聲明
THE END
喜歡就支持一下吧
點贊7 分享