首頁 > php框架 > Laravel > 主體

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

青灯夜游
發布: 2022-03-03 19:55:06
轉載
2589 人瀏覽過

如何使用 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 的隊列機制,了解一下隊列的使用場景的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板