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

Laravel: Task Scheduling trong laravel

21.09.2020

0/5 (0 Reviews)

Hôm nay mình sẽ tổng hợp và giới thiệu cho các bạn một bài khá hay về 1 tính năng của Laravel. Đó là Task Scheduling (Lập lịch làm việc) có thể áp dụng vào việc thiết kế web đặt lịch, sự kiện hoặc các website có tính chất cần vận hành theo lịch định trước nào đó.

    Hôm nay mình sẽ tổng hợp và giới thiệu cho các bạn một bài khá hay về 1 tính năng của Laravel. Đó là Task Scheduling (Lập lịch làm việc) có thể áp dụng vào việc thiết kế web đặt lịch, sự kiện hoặc các website có tính chất cần vận hành theo lịch định trước nào đó.

    Giới thiệu về Task Scheduling trong laravel

    Trước đây, có thể bạn đã từng tạo một Cron cho một tác vụ nào đó mà bạn muốn lập lịch để chạy trên server của bạn. Tuy nhiên, sẽ khá phiền phức nếu bạn muốn thay đổi hoặc thêm các schedules mới khi bạn phải SSH đến server của bạn để thực hiện việc này.

    Lệnh scheduler của Laravel cho phép bạn xác định lịch trình của mình một cách dễ dàng ngay trong chính Laravel. Khi sử dụng scheduler, bạn chỉ cần duy nhất một Cron entry trên server của bạn. Lịch trình làm việc của bạn sẽ được định nghĩa trong phương thức schedule trên file app/Console/Kernel.php. Để giúp bạn bắt đầu, một ví dụ đơn giản được định nghĩa trong phương thức:

    Starting The Scheduler

    Khi sử dụng scheduler, bạn chỉ cần thêm 1 mục Cron sau vào server của bạn. Nếu bạn không biết làm thế nào để thêm các mục Cron vào server của mình, hãy xem xét sử dụng 1 service như mà có thể quản lý các mục Cron cho bạn:

    * * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
    

    Cron này sẽ gọi lệnh Laravel scheduler mỗi phút. Khi lệnh schedule:run được thực thi, Laravel sẽ tìm biểu thức scheduled task của bạn và chạy các task đến kỳ hạn.

    Defining Schedules

    Bạn có thể định nghĩa tất cả các scheduled task trong phương thức schedule của lớp App\Console\Kernel. Để bắt đầu, hãy xem ví dụ về lập lịch 1 task. Trong ví dụ này, chúng ta sẽ lạp 1 Closure để được gọi mỗi ngày vào lúc nửa đêm. Trong Closure, chúng ta sẽ thực hiện một truy vấn cơ sở dữ liệu để xóa bảng:

    <?php
    
    namespace App\Console;
    
    use DB;
    use Illuminate\Console\Scheduling\Schedule;
    use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
    
    class Kernel extends ConsoleKernel
    {
        /**
         * The Artisan commands provided by your application.
         *
         * @var array
         */
        protected $commands = [
            \App\Console\Commands\Inspire::class,
        ];
    
        /**
         * Define the application's command schedule.
         *
         * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
         * @return void
         */
        protected function schedule(Schedule $schedule)
        {
            $schedule->call(function () {
                DB::table('recent_users')->delete();
            })->daily();
        }
    }
    

    Ngoài việc lên kế hoạch cho Closure, bạn cũng có thể lập lịch các lên Artisan và các lệnh hệ điều hành. Ví dụ, bạn có thể sử dụng phương thức command để lập lịch cho 1 Artisan command sử dụng tên command hoặc class:

    $schedule->command('emails:send --force')->daily();
    
    $schedule->command(EmailsCommand::class, ['--force'])->daily();
    

    Lệnh exec có thể ddwwocj sử dụng để đưa ra các lệnh cho hệ điều hành:

    $schedule->exec('node /home/forge/script.js')->daily();
    

    Schedule Frequency Options

    Dĩ nhiên, có nhiều lựa chọn về thời gian để bạn có thể lập lịch cho task của mình:

    Những phương thức này có thể được kết hợp với các ràng buộc bổ sung để tạo ra các lịch trình tinh vi hơn nữa mà chỉ chạy trong những ngày nhất định trong tuần. Ví dụ: để lập lịch một lệnh để chạy hàng tuần vào thứ hai:

    // Run once per week on Monday at 1 PM...
    $schedule->call(function () {
        //
    })->weekly()->mondays()->at('13:00');
    
    // Run hourly from 8 AM to 5 PM on weekdays...
    $schedule->command('foo')
              ->weekdays()
              ->hourly()
              ->timezone('America/Chicago')
              ->between('8:00', '17:00');
    

    Dưới đây là danh sách các ràng buộc thời gian bổ sung:

    Between Time Constraints

    Phương thức between có thể được sử dụng để hạn chế việc thực hiện một task dựa trên khoảng thời gian trong ngày:

    $schedule->command('reminders:send')
                        ->hourly()
                        ->between('7:00', '22:00');
    

    Tương tự, phương thức exceptBetween được sử dụng để loại trừ việc thực hiện một task trong một khoảng thời gian:

    $schedule->command('reminders:send')
                        ->hourly()
                        ->unlessBetween('23:00', '4:00');
    

    Preventing Task Overlaps

    Theo mặc định, các task scheduled sẽ được chạy ngay cả khi instance trước đó của task vẫn đang chạy. Để ngăn chặn điều này, bạn có thể sử dụng phương thức withoutOverLapping

    $schedule->command('emails:send')->withoutOverlapping();
    

    Trong ví dụ này, câu lệnh Artisan emails:send sẽ được chạy mỗi phút nếu nó chưa chạy. Phương pháp withoutOverLapping đặc biệt hữu ích nếu bạn các task thay đổi đáng kể trong thời gian thực hiện của chúng, ngăn không cho bạn dự đoán chính xác thời gian của một task nhất định sẽ mất.

    Maintenance Mode

    scheduled task của Laravel sẽ không chạy khi Laravel đang ở vì họ không muốn công việc của bạn can thiệp vào bất kỳ bảo trì chưa hoàn thành nào bạn có thể thực hiện trên server của bạn, Tuy nhiên, nếu bạn muốn buộc một task chạy ngay cả trong chế độ bảo trì, bạn có thể sử dụng phương thức evenInMaintenanceMode:

    $schedule->command('emails:send')->evenInMaintenanceMode();
    

    Task Output

    Laravel scheduler cung cấp một số phương thức thuận tiện để làm việc với output được tạo ra bởi các scheduled task. Đầu tiên, bằng cách sử dụng phương thức sendOutputTo, bạn có thể gửi output tới một file để kiểm duyệt sau:

    $schedule->command('emails:send')
             ->daily()
             ->sendOutputTo($filePath);
    

    Nếu bạn muốn nối output vào 1 file nhất định, bạn có thể sử dụng phương thức appendOutputTo:

    $schedule->command('emails:send')
             ->daily()
             ->appendOutputTo($filePath);
    

    Sử dụng phương thức emailOutputTo, bạn có thể gửi email output đến 1 địa chỉ email bạn chọn. Trước khi gửi email output của một task, bạn nên cấu hình các của Laravel:

    $schedule->command('foo')
             ->daily()
             ->sendOutputTo($filePath)
             ->emailOutputTo('');
    

    Task Hooks

    Sử dụng phương thức beforeafter, bạn có thể chỉ định mã được thực hiện trước và sau khi công việc đã được lập lịch hoàn tất.

    $schedule->command('emails:send')
             ->daily()
             ->before(function () {
                 // Task is about to start...
             })
             ->after(function () {
                 // Task is complete...
             });
    
    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