Tìm hiểu queue trong Laravel

Tìm hiểu queue trong Laravel

Giới thiệu:

  • Khi xây dựng ứng dụng web, bạn có thể có một số tác vụ cần nhiều thời gian xử lý, chẳng hạn như: gửi mail, phân tích cú pháp và lưu trữ tệp CSV đã tải lên. Rất may, Laravel cung cấp cho bạn một giải pháp cho phép bạn dễ dàng tạo các công việc (job) xếp vào hàng đợi có thể được xử lý ở chế độ nền (chạy nền ở đây tức là không yêu cầu user phải đợi). Bằng cách chuyển các tác vụ tốn nhiều thời gian vào hàng đợi (queue), trang web của bạn sẽ có tốc độ phản hồi nhanh chóng cung cấp trải nghiệm tốt cho người dùng.
  • Laravel cung cấp rất nhiều loại queue để sử dụng như Amazon SQS, Redis, Database (trong bài này tập chung vào queue database). Các tùy chọn cấu hình được lưu trong file config/queue.php

Tích hợp queue vào dự án Laravel (queue database)

Vì là một trong những thành phần của laravel nên việc dùng queue cũng rất đơn giản

  1. Tùy chỉnh file cấu hình .env
    Mở file .env tìm dòng QUEUE_DRIVER=sync (mặc định queue trong laravel đang để sync) đổi thành

QUEUE_DRIVER=database

2. Migration table cho queue
Để sử dụng queue driver database, chúng ta cần một bảng lưu trữ các jobs nên cần có một migration. Để khởi tạo các table dùng Artisan:

php artisan queue:table # Tạo ra các migrations mới liên quan tới queue (gồm 2 table jobs và fail_jobs)
php artisan migrate # Migrate các migrations mới tạo ra

3. Tạo job classes
Mặc định các job được lưu ở thư mục app/Jobs. Tạo mới một job dùng Artisan:

php artisan make:job SendWelcomeEmail

Một class mới (SendWelcomeEmail) được tạo trong thư mục app/Jobs và class này được implement interface Illuminate\Contracts\Queue\ShouldQueue cho biết job này cần đẩy vào queue thay vì chạy bộ.

**Cấu trúc của JobClass: **
Trong JobClass cũng không có gì phức tạp, cần lưu ý duy nhất hàm handle, hàm này sẽ thực hiện khi job được queue gọi xử lý.

<?php

namespace App\Jobs;

use App\User;
use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendWelcomeEmail extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $user;

    /**
     * Create a new job instance.
     *
     * @param  User  $user
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Execute the job.
     *
     * @param  Mailer  $mailer
     * @return void
     */
    public function handle(Mailer $mailer)
    {
        echo 'thuc hien gui mail';
    }
}

Trong ví dụ trên, chúng ta thấy có thể truyền các tham số từ hàm khởi tạo (có thể truyền một instant của model, trong ví dụ trên là $user). Trong JobClass sử dụng trait SerializesModels nên khi công việc đuơc đưa vào queue, các Eloquent model sẽ được serialize (chuyển data sang dạng string) lưu xuống database (bảng jobs) và được unserialize khi job được xử lý.

Trườn hợp xảy ra lỗi trong quá trình thực thi job, job đấy sẽ được đẩy ngược vào queue để chạy lại (số lần chạy lại tùy thuộc vào thông số --tries khi thực hiện câu lệnh queue:work. Quá số lần chạy lại thì job đó sẽ được đẩy vào table fail_jobs

4. Đưa job vào queue
Để đẩy job vào queue cần sử dụng trait DispatchesJobs. Trait này cung cấp phương thức đẩy job vào queue (Dispatch)

$this->dispatch(new SendWelcomeEmail($user)); // chỉ cần khởi tạo job và truyền param, dùng phương thức dispatch để đưa vào queue

Khi đã đưa vào queue rồi, bước cuối cùng là chạy queue dùng artisan:

php artisan queue:work

Tài liệu tham khảo: