Làm thứ làm cho Laravel Request của bạn thú vị hơn

Laravel 5.5 – Queue (Giới thiệu và sử dụng)

Laravel 5.5 – Queue (Giới thiệu và sử dụng)

Hi các bạn,

Đôi khi trong controller, chúng ta có 1 cái task (ví dụ như gửi email), nó chiếm khá là nhiều thời gian (tầm 2-5s) để xử lý chẳng hạn, mà task của nó thuộc dạng ko ảnh hưởng tới flow của chúng ta nhiều. Nếu chúng ta cứ đi theo kiểu thông thường thì main thread của chúng ta lại tốn khá là nhiều thời gian.

Nhưng rất may, Laravel đã có 1 tính năng là Queue, hỗ trợ ta chạy 1 task bất kỳ ở background, push nó vào hàng đợi và Laravel sẽ xử lý nó tuần tự theo hàng đợi đó.

Link document của Laravel: https://laravel.com/docs/5.5/queues

1/ Cấu hình Queue

Laravel hỗ trợ lưu trữ Queue rất nhiều loại như database, redis,… Ở đây mình sẽ hướng dẫn các bạn về database.

Đầu tiên, ta mở file .env và tìm QUEUE_DRIVER, sửa lại như sau (mặc định cái này là sync):

QUEUE_DRIVER=database

Tiếp theo, ta mở CMD/Terminal lên tại root Laravel, chạy 2 lệnh này:

php artisan queue:table

php artisan migrate

Lệnh đầu sẽ khởi tạo migration table dành cho Queue, lệnh sau sẽ update lên database luôn. Mọi Queues đều được Laravel quản lý tại database.

Vậy là ta đã cấu hình xong cho Queue sử dụng database. Nếu bạn nào sử dụng redis hay cái khác thì nhớ vào config/queue.php để cấu hình nữa nhé (mình ko hướng dẫn redis âu)

2/ Định nghĩa Queue Task

Vẫn dùng CMD/Terminal, ta chạy lệnh này để tạo ra Task mình muốn.

php artisan make:job <name>

ví dụ: php artisan make:job ProcessUpdateUser

Sau khi tạo xong, các bạn vào thư mục app sẽ thấy folder Jobs đã được tạo, và bên trong sẽ có class ProcessUpdateUser, mặc định như sau:

<?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;

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

Trong class này, ta có thể thực thi thoải mái, tạo ra các properties hay methods,…

Tại hàm khởi tạo, ta có thể nhận vào giá trị tùy ý để thực hiện Task mà ta cần.

Và tại hàm handle, sẽ là nơi mà ta định nghĩa cho Task của chúng ta thực hiện, làm gì đó,…

Ví dụ mình nhận vào $user_id và update user nhé.

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

    private $user_id;

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

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        User::updateAuditLogUser($this->user_id);
        ....
    }
}

Ví dụ vậy 😀

3/ Khởi tạo Queue Task

Để khởi tạo Queue, rất đơn giản, ta chỉ cần import Queue Task của chúng ta vào và chạy 1 dòng đơn giản này:

ProcessAfterAttendance::dispatch($user_id)

Khi ta dispatch 1 queue, nó sẽ lập tức cập nhập thông tin queue của chúng ta đã dispatch lên DB, và background task sẽ tự động check và chạy liền ngay lập tức nếu đã tới lượt nó (Xem bước 4 để biết background task).

Ta cũng có thể delay cái dispatch này thêm 1 số thời gian nhất định (vd sẽ chạy queue task này sau 30s, 60s,…). (Tối đa hình như 10-15p thì fải):

ProcessAfterAttendance::dispatch($user_id)
			->delay(now()->addSeconds(30)); // run after 30 seconds

Hàm now() này hỗ trợ ta tạo ra 1 Carbon instance với thời gian hiện tại, nó rất nhiều method như addMinutes, addHours,… về vụ này các bạn cứ xài PHPStorm, nó sẽ show hết ra thôi (hoặc xem document của Carbon PHP) 😀

Ta sẽ truyền các biến cần thiết ở hàm khởi tạo Queue Task vào hàm dispatch nhé.

Vậy là ta đã khởi tạo xong, nhưng khi ta thực hiện, nó chưa chạy đâu kể cả qua 60s, ta cần phải Running Work nữa.

4/ Running Work (Quan trọng)

Nếu thiếu bước này, thì Task vẫn được tạo ra và insert vào database table jobs, nhưng quá thời gian nó sẽ ko chạy, ko bao giờ chạy.

Vậy nên để nó chạy được, ta lại tiếp tục dùng CMD/Terminal chạy lệnh:

php artisan queue:work

Lệnh này nó sẽ chạy 1 vòng lặp vô tận để kiểm tra liên tục queue của bạn để nó có thể process.

Lưu ý: khi chạy lệnh này, nó sẽ treo luôn cmd/terminal để nhận event và process, nếu các bạn tắt thì nó sẽ ko thực thi nữa cho đến khi nào Running lại.

Ở linux terminal, ta có thể dùng supervisor để cấu hình lệnh này chạy ẩn dưới background (Laravel có hướng dẫn).

Mỗi khi bắt đầu chạy, nó sẽ xuất ra màn hình trạng thái Processing như bên dưới hình, và khi chạy xong task, nó sẽ chuyển qua Processed.

Laravel Queue

5/ Lời kết

Lưu lại và sẽ có lúc cần xài thôi các bạn :D, nay mình gặp vấn đề này và phải cần xài vụ này rùi 😀

À mà, mỗi Laravel có cách Queue khác nhau thì phải, các bản Laravel 5.5 trở xuống các bạn nên lên Documentation của Laravel theo dõi nhé, nó cũng tương tự như 5.5 thôi chứ ko khác gì nhiều đâu 😀

Cái này nó khác với Cron Job nhé các bạn, Cron Job là ta thực hiện tuần tự liên tục sau x thời gian 😀

Cám ơn các bạn đã theo dõi!

# Laravel 5, # Laravel Queue, # Queue

facebook
Seth Phát

Seth Phát

Mình là Phát - biệt danh Seth Phát. Hiện đang là một Sr. Full-Stack Engineer. Mình là một người yêu thích và đam mê lập trình và hiện tại đang theo về phần Web là chủ yếu. Mạnh Back-end và khá Front-end, vẫn đang theo đều cả 2 :v. Còn gì bằng khi được làm những thứ mà mình yêu thích, đam mê ;)

One thought on “Laravel 5.5 – Queue (Giới thiệu và sử dụng)

Comments are closed.

Bình luận qua Facebook