Tìm kiếm bài viết

Laravel: Tìm hiểu về queues. (Phần 1)

12.10.2020

5.0/5 (1 Reviews)

Tìm hiểu về queues trong laravel. Laravel queues cung cấp một API thống nhất trên nhiều loại queue backend khác nhau, như Beanstalk, Amazon SQS, Redis, hoặc ngay cả cở sở dữ liệu quan hệ.

    Tìm hiểu về queues trong laravel

    Laravel queues cung cấp một API thống nhất trên nhiều loại queue backend khác nhau, như Beanstalk, Amazon SQS, Redis, hoặc ngay cả cở sở dữ liệu quan hệ. Queues cho phép bạn hoãn lại tiến trình của task, như gửi mail, cho đến một thời gian nào đó. Việc hoãn những task mất nhiều thời gian này sẽ làm tăng tốc độ cho ứng dụng web của bạn.

    Cấu hình queue được lưu tại thư mục config/queue.php. Trong file này bạn sẽ tìm kết nối với mỗi queue drivers mà bạn thêm vào framework, nó bao gồm , , , và synchronous driver sẽ thực hiện công việc ngay lập tức (cho local sử dụng). Một null queue driver cũng được include và đơn giản là thực hiện loại bỏ queued jobs.

    Connections Vs. Queues

    Trước khi bắt đầu với Laravel queues, điều quan trọng là bạn cần hiểu sự khác biệt giữa "connections" và "queues". Trong file cấu hình config/queue.php, có một tùy chọn connections. Tùy chọn này sẽ định nghĩa một connection cụ thể vào một backend service như Amazon SQS, Beanstalk, hoặc Redis. Tuy nhiên, bất kỳ queue connection có thể có nhiều "queues" mà có thể được coi như các stacks khác nhau hoặc các queued jobs.

    Chú ý rằng mỗi ví dụ cấu hình connection trong file cấu hình queue chứa một thuộc tính queue. Đây là queue mặc định mà các job sẽ được gửi tới khi chúng được gửi tới một connection. Nói cách khác, nếu bạn gửi một job mà không xác định rõ queue nào cần gửi đến, job sẽ được đặt trên queue được đinh nghĩa trong queue attribute của cấu hình connection:

    // This job is sent to the default queue...
    dispatch(new Job);
    
    // This job is sent to the "emails" queue...
    dispatch((new Job)->onQueue('emails'));
    

    Một số ứng dụng có thể không cần phải push các job vào multiple queue, thay vì prefer 1 simple queue. Tuy nhiên, việc đẩy (push) job cho nhiều queue có thể đặc biệt hữu ích cho các ứng dụng muốn sắp xếp thứ tự ưu tiên hoặc phân công công việc được xử lý, vì Laravel queue worker cho phép bạn chỉ định các queue cần xử lý theo độ ưu tiên. Ví dụ, bạn muốn push các công việc vào high queue, bạn có thể chạy 1 worker có độ ưu tiên cao hơn:

    php artisan queue:work --queue=high,default
    

     

    Driver Prerequisites

     

    Database

    Để sử dụng database queue driver, bạn sẽ cần một database để giữ các job. Để generate một migration tạo ra table này, chạy lệnh Artisan queue:table. Khi migration được khởi tạo, bạn có thể migrate database của bạn bằng cách sử dụng câu lệnh migrate.

    php artisan queue:table
    
    php artisan migrate
    

    Redis

    Để sử dụng redis queue driver, bạn nên cấu hình một kết nối Redis database trong file cấu hình config/database.php. Nếu kết nối Redis queue của bạn sử dụng một Redis Cluster, tên queue của bạn phải chứa một . Điều này là cần thiết để đảm bảo tất cả các Redis key cho một queue nhất định được đặt vào cùng một vị trí hash giống nhau.

    'redis' => [
        'driver' => 'redis',
        'connection' => 'default',
        'queue' => '{default}',
        'retry_after' => 90,
    ],
    

     

    Other Driver Prerequisites

    Các dependence sau đây là cần thiết cho các listed queue driver.

    • Amazon SQS: aws/aws-sdk-php ~3.0
    • Beanstalkd: pda/pheanstalk ~3.0
    • Redis: predis/predis ~1.0

     

    Creating Jobs

     

    Generating Job Classes

    Theo mặc định, tất cả các job có thể xếp hàng cho ứng dụng của bạn được lưu trữ trong thư mục app/Jobs Nếu thư mục app\Jobs không tồn tại, nó sẽ được tạo ra khi bạn chạy lệnh Artisan make:job. Bạn có thể tạo ra 1 queued job mới sử dụng Artisan CLI

    php artisan make:job SendReminderEmail
    

    Class được tạo sẽ implement interface Illuminate\Contracts\Queue\ShouldQueue, chỉ ra cho Laravel rằng job cần được đẩy lên hàng đợi để chạy không đồng bộ

    Class Structure

    Các class Job rất đơn giản, thường chỉ chứa một phương thức handle được gọi khi job được xử lý bơi queue. Để bắt đầu, hãy xem một ví dụ về class job. trong ví dụ này, ta sẽ giả vờ chúng ta quản lý 1 dịch vụ xuất bản podcast và cần xử lý file podcast trước khi chúng được xuất bản:

    <?php
    
    namespace App\Jobs;
    
    use App\Podcast;
    use App\AudioProcessor;
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    
    class ProcessPodcast implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        protected $podcast;
    
        /**
         * Create a new job instance.
         *
         * @param  Podcast  $podcast
         * @return void
         */
        public function __construct(Podcast $podcast)
        {
            $this->podcast = $podcast;
        }
    
        /**
         * Execute the job.
         *
         * @param  AudioProcessor  $processor
         * @return void
         */
        public function handle(AudioProcessor $processor)
        {
            // Process uploaded podcast...
        }
    }
    

    Trong ví dụ này, lưu ý rằng chúng ta đã có thể pass qua trực tiếp đến construct của queue job. Vì SerializesModels trait mà job được sử dụng, các Eloquent model sẽ ddwwocj sắp xếp theo thứ tự và không tuần tự một cách hợp lý khi job đang được xử lý. Nếu queue job của bạn chấp nhận một Eloquent model trong constructor của nó, chỉ có định danh cho model sẽ được tuần tự hóa vào queue. Khi queue job được xử lý, queue system sẽ tự động lấy lại model instance từ database. Tất cả đều minh bach cho ứng dụng của bạn và ngăn ngừa các vấn đề có thể phát sinh từ việc serializing tất cả các instance của Eloquent model.

    Phương thức handle được gọi khi job ddwwocj xử lý bởi queue. Lưu ý rằng chúng ta có thể type-hint dependence trên phương thước handle của job. Laravel tự động inject các dependence này.

     

    Dispatching Jobs

     

    Một khi bạn đã viết class job của bạn, bạn có thể gửi nó đi bằng cách sử dụng dispatch helper. Một đối số duy nhất bạn cần pass cho dispatch helper là một instance của job:

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Jobs\ProcessPodcast;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    
    class PodcastController extends Controller
    {
        /**
         * Store a new podcast.
         *
         * @param  Request  $request
         * @return Response
         */
        public function store(Request $request)
        {
            // Create podcast...
    
            dispatch(new ProcessPodcast($podcast));
        }
    }
    

     

    Delayed Dispatching

     

    Nếu bạn muốn trì hoãn việc thực hiện job đã được xếp hàng, bạn có thể sử dụng phương thức delay trên instance job của bạn. Phương thức delay được cung cấp bởi Illuminate\Bus\Queueable trait, được include mặc định trên tất cả các class job được tạo ra. Ví dụ, chúng ta hãy chỉ định một job không có sẵn để xử lý cho đến 10 phút sau khi nó đc dispatch:

    <?php
    
    namespace App\Http\Controllers;
    
    use Carbon\Carbon;
    use App\Jobs\ProcessPodcast;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    
    class PodcastController extends Controller
    {
        /**
         * Store a new podcast.
         *
         * @param  Request  $request
         * @return Response
         */
        public function store(Request $request)
        {
            // Create podcast...
    
            $job = (new ProcessPodcast($podcast))
                        ->delay(Carbon::now()->addMinutes(10));
    
            dispatch($job);
        }
    }
    

     

    Customizing The Queue & Connection

     

    Dispatching To A Particular Queue

    Bằng cách push các job đến các queue khác nhau, bạn có thể phân loại job được xếp hàng và thâm chí ưu tiên số worker bạn chỉ định cho các queue khác nhau. Lưu ý rằng điều này không push job đến các queue "connections" khác nhau như được định nghĩa bởi file cấu hình queue của bạn, nhưng chỉ các queue chỉ định trong một single connection. Để xác định queue, sử dụng phương thức onQueue trên instance job:

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Jobs\ProcessPodcast;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    
    class PodcastController extends Controller
    {
        /**
         * Store a new podcast.
         *
         * @param  Request  $request
         * @return Response
         */
        public function store(Request $request)
        {
            // Create podcast...
    
            $job = (new ProcessPodcast($podcast))->onQueue('processing');
    
            dispatch($job);
        }
    }
    

    Dispatching To A Particular Connection

    Nếu bạn đang làm việc với multiple queue connection, bạn có thể chỉ định connection nào để push một job. Để chỉ định connection, sử dụng phương thức onConnection trên instance job:

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Jobs\ProcessPodcast;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    
    class PodcastController extends Controller
    {
        /**
         * Store a new podcast.
         *
         * @param  Request  $request
         * @return Response
         */
        public function store(Request $request)
        {
            // Create podcast...
    
            $job = (new ProcessPodcast($podcast))->onConnection('sqs');
    
            dispatch($job);
        }
    }
    

    Dĩ nhiên, bạn có thể nối các phương thức onConnectiononQueue để chỉ đinh connection và queue cho một job.

    $job = (new ProcessPodcast($podcast))
                    ->onConnection('sqs')
                    ->onQueue('processing');
    

     

    Specifying Max Job Attempts / Timeout Values

     

    Max Attempts

    Một cách tiếp cận để chỉ định số lần tối đa của job có thể được thực hiện là thông qua --tries trên câu lệnh Artisan:

    php artisan queue:work --tries=3
    

    Tuy nhiên, bạn có thể thực hiện một cách tiếp cận chi tiết hơn bằng cách xác định số lần tối đa trên job class. Nếu số lần tối đa của attempt được chỉ đinh trên job, nó sẽ được ưu tiên hơn giá trị được cung cấp bởi dòng lệnh:

    <?php
    
    namespace App\Jobs;
    
    class ProcessPodcast implements ShouldQueue
    {
        /**
         * The number of times the job may be attempted.
         *
         * @var int
         */
        public $tries = 5;
    }
    

    Timeout

    Tương tự như vậy, số giây tối đa mà các job được chạy có thể chỉ định bằng cách sử dụng --timeout trên dòng lệnh Artisan:

    php artisan queue:work --timeout=30
    

    Tuy nhiên, bạn cũng có thể chỉ định số giây tối đa mà 1 job được chạy trên class job. Nếu thời gian được chỉ định cho job, nó sẽ được ưu tiên hơn khi chỉ định trên dòng lệnh:

    <?php
    
    namespace App\Jobs;
    
    class ProcessPodcast implements ShouldQueue
    {
        /**
         * The number of seconds the job can run before timing out.
         *
         * @var int
         */
        public $timeout = 120;
    }
    

     

    Tài liệu: Tại trang chủ của

    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    Kubernetes bài 6 - Vận hành k8s Day-Two Operations và Quản trị bằng GitOps

    22.05.2026

    Khi cụm Kubernetes của bạn đã được bảo mật cấu hình, tối ưu tài nguyên và thiết lập tự phục hồi, câu hỏi đặt ra là làm sao để duy trì sự ổn định đó trong nhiều năm tiếp theo mà không bị phụ thuộc

    thumbnail

    Kubernetes bài 5 - bảo mật Cloud Native và chuẩn DevSecOps cho K8s

    22.05.2026

    Việc siết chặt an ninh (Hardening) không phải là cấu hình một vài thông số rồi bỏ đó, mà là một tư duy phòng thủ chiều sâu.

    thumbnail

    Kubernetes bài 4 - Tối ưu Resource Auto-Healing và Scale Zero-Downtime

    22.05.2026

    Bài viết này sẽ đi sâu vào các cơ chế ở tầng Kernel giúp hệ thống tự phục hồi, chống lại các đợt tấn công cạn kiệt tài nguyên và cập nhật phiên bản mới mà người dùng không hề hay biết.

    thumbnail

    Kubernetes bài 3 - Bảo mật cấu hình k8s và config Security trên Production

    22.05.2026

    Kubernetes giải quyết bài toán này bằng hai đối tượng chuyên biệt nhưng nếu không hiểu rõ bản chất bảo mật ở tầng dưới, bạn đang tự tay dâng toàn bộ chìa khóa hệ thống cho hacker.

    thumbnail

    Kubernetes bài 2 - Mạng lưới k8s và luồng Traffic ở Packet Level

    22.05.2026

    Pod không chỉ là một container: Rất nhiều người nhầm lẫn Pod 1-1 với Container. Thực chất, Pod là đơn vị triển khai nhỏ nhất, có thể chứa một hoặc nhiều container

    Mục lục bài viết