iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Modern Web

Laravel 9 漫遊,享受魔法般的極速網頁開發體驗系列 第 25

Day 25:快取之外的加速方式:透過 queue 非同步的處理費時任務

  • 分享至 

  • xImage
  •  

昨天我們提到了怎麼利用快取,來讓我們的服務提高效率。

不過有些時候,即使用上了快取,用戶的體驗還是沒有辦法提升到令人滿意的程度。

這些時候,我們可以考慮將一些比較費時的任務,轉換到排程(Queue)內處理。

今天,我們來看看在 Laravel 內怎麼實作這件事情!

首先,我們先看 queue 的設置,在 Laravel 內,放在 config/queue.php

    'default' => env('QUEUE_CONNECTION', 'sync'),

這邊要注意, sync 這個驅動並不會實際的將任務分配進 queue,而是會等任務做完了之後再往下進行。

如果是實際上線的產品,或者你想要練習開發中實際運作 queue,建議可以用 redis 來操作

        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => env('REDIS_QUEUE', 'default'),
            'retry_after' => 90,
            'block_for' => null,
            'after_commit' => false,
        ],

這邊建議可以在 .env 內設置 REDIS_QUEUE

設置沒有問題之後,我們可以開始建立任務。

這邊相信讀者(略

./vendor/bin/sail artisan make:job ProcessPodcast

   INFO  Job created successfully.

就會建立在 app/Jobs/ProcessPodcast.php 裡面

<?php

namespace App\Jobs;

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

class ProcessPodcast 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()
    {
        //
    }
}

這邊就可以撰寫你想要的邏輯了

比方說,既然是 ProcessPodcast,你可能會想要注入 Podcast

use App\Models\Podcast;

    public function __construct(Podcast $podcast)
    { }

管理好了之後,可以使用 dispatch 來發布 Job

class PodcastController extends Controller
{

    public function store(Request $request)
    {
        $podcast = Podcast::create(/* ... */);
        ProcessPodcast::dispatch($podcast);
    }
}

如果你選用了不會立刻執行的設置,但是某些狀況下,希望能立刻執行該任務,可以用 dispatchSync()

ProcessPodcast::dispatchSync($podcast);

如果你希望任務發布後,要等一段時間才有機會被執行,可以用 delay()

ProcessPodcast::dispatch($podcast)
	->delay(now()->addMinutes(10));

任務發布的部分,大概就介紹這幾種做法。

發布任務到 queue 裡面後,下一步就是找人去執行這些任務了。

這邊我們可以簡單地透過指令呼叫 queue worker

./vendor/bin/sail artisan queue:work

呼叫之後, worker 就會起來,開始運作該執行的任務了。

這邊要注意,即使任務全部執行完畢, queue worker 也不會終止,而是會持續的等 queue 出現新任務。


今天有關 queue 的基礎,就先介紹到這邊。其實 queue 還有很多可以介紹的細節,比方說怎麼定義一個任務失敗,讓失敗的任務可以放在失敗任務的表內。

以及,怎麼規劃 worker 在某個時間點,重新處理這些失敗的任務。是將這些任務清除掉呢,還是重新執行?

有關 queue worker,也可以討論這個程式是不是會意外中斷,為了避免意外中斷,我們可以用 supervisor 監督該 worker

apt-get install supervisor

不過,這些議題都比較進階了!所以我們就以後再說吧!各位明天見!


上一篇
Day 24:Laravel 9 對快取的操作
下一篇
Day 26:協助開發中除錯的好幫手:Laravel Telescope
系列文
Laravel 9 漫遊,享受魔法般的極速網頁開發體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言