Laravel中隊列的使用


以laravel5.5為例子:

1.配置隊列:composer require "predis/predis:~1.0"

a.在ENV中配置:QUEUE_DRIVER=redis

b.配置表,失敗時隊列的失敗信息內容會存到此表里。命令:php artisan queue:failed-table

c.生成記錄失敗的數據表:php aritsan migrate

2.生成一個任務類出來:php artisan make:job TranslateSlug

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use App\Models\Topic;
use App\Handlers\SlugTranslateHandler;

class TranslateSlug implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $topic;

    public function __construct(Topic $topic)
    {
        // 隊列任務構造器中接收了 Eloquent 模型,將會只序列化模型的 ID
        $this->topic = $topic;
    }

    public function handle()
    {
        // 請求百度 API 接口進行翻譯
        $slug = app(SlugTranslateHandler::class)->translate($this->topic->title);

        // 為了避免模型監控器死循環調用,我們使用 DB 類直接對數據庫進行操作
        \DB::table('topics')->where('id', $this->topic->id)->update(['slug' => $slug]);
    }
}

  

該類實現了 Illuminate\Contracts\Queue\ShouldQueue 接口,該接口表明 Laravel 應該將該任務添加到后台的任務隊列中,而不是同步執行。

引入了 SerializesModels trait,Eloquent 模型會被優雅的序列化和反序列化。隊列任務構造器中接收了 Eloquent 模型,將會只序列化模型的 ID。這樣子在任務執行時,隊列系統會從數據庫中自動的根據 ID 檢索出模型實例。這樣可以避免序列化完整的模型可能在隊列中出現的問題。

handle 方法會在隊列任務執行時被調用。值得注意的是,我們可以在任務的 handle 方法中可以使用類型提示來進行依賴的注入。Laravel 的服務容器會自動的將這些依賴注入進去,與控制器方法類似。

還有一點需要注意,我們將會在模型監控器中分發任務,任務中要避免使用 Eloquent 模型接口調用,如:create()update()save() 等操作。否則會陷入調用死循環 —— 模型監控器分發任務,任務觸發模型監控器,模型監控器再次分發任務,任務再次觸發模型監控器.... 死循環。在這種情況下,使用 DB 類直接對數據庫進行操作即可。

 

3.任務分發:

<?php

namespace App\Observers;

use App\Models\Topic;
use App\Jobs\TranslateSlug;

// creating, created, updating, updated, saving,
// saved,  deleting, deleted, restoring, restored

class TopicObserver
{
    public function saving(Topic $topic)
    {
        // XSS 過濾
        $topic->body = clean($topic->body, 'user_topic_body');

        // 生成話題摘錄
        $topic->excerpt = make_excerpt($topic->body);

        // 如 slug 字段無內容,即使用翻譯器對 title 進行翻譯
        if ( ! $topic->slug) {

            // 推送任務到隊列
            dispatch(new TranslateSlug($topic));
        }
    }
}

4.開始測試,監聽 php artisan queue:listen


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM