- vừa được xem lúc

Task Scheduling trong Laravel

0 0 19

Người đăng: phptojvb

Theo Viblo Asia

Giới thiệu

  • 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 1 lệnh Cron 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.
  • VD : Với Task Scheduling, bạn có thể dễ dàng định lịch các tác vụ như gửi email hàng ngày, xóa các bản ghi cũ, cập nhật dữ liệu từ các nguồn bên ngoài và nhiều hơn nữa. Laravel cung cấp một cú pháp đơn giản để định nghĩa các tác vụ và lịch trình chúng, đảm bảo rằng các tác vụ được thực hiện đúng thời gian và đúng cách.

1.Khởi tạo Schedules

Bạn có thể khởi tạo các scheduled task trong method schedule trong class App\Console\Kernel. Ví dụ dưới đây là 1 schedule task chạy query xoá table vào mỗi ngày:

<?php namespace App\Console; use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\DB; class Kernel extends ConsoleKernel
{ /** * 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 cách sử dụng Closure khi khai báo schedule, bạn cũng có thể gọi đến một PHP class bất kì mà có chưa __invoke() method:

$schedule->call(new DeleteRecentUsers)->daily();

Để xem tổng quan các Scheduled tasks và thời gian tiếp theo mà nó sẽ chạy bạn có thể sử dụng câu lệnh command sau:

php artisan schedule:list

image.png

2. Scheduling cho artisan command

Bạn cũng có thể lên lịch chạy cho các lệnh command bằng cách truyền trực tiếp câu lệnh command hoặc truyền class của command đó:

use App\Console\Commands\SendEmailsCommand; $schedule->command('emails:send Taylor --force')->daily(); $schedule->command(SendEmailsCommand::class, ['Taylor', '--force'])->daily();

Khi sử dụng tên class thì các argument bạn muốn truyền vào sẽ phải dưới dạng array

3. Scheduling Queued Jobs

Để lên lịch đưa 1 job nào đó vào hàng đợi queue, bạn dùng tới job method. Ví dụ như sau:

use App\Jobs\Heartbeat; $schedule->job(new Heartbeat)->everyFiveMinutes();

4. Scheduling Shell Commands

Ngoài ra bạn cũng có thể lên lịch cho 1 lệnh command bất kì:

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

5. Các tuỳ chọn custom thời gian Scheduling

Các tuỳ chọn về tần suất thực hiện:

Method Description
->cron('* * * * *'); Run the task on a custom cron schedule
->everyMinute(); Run the task every minute
->everyTwoMinutes(); Run the task every two minutes
->everyThreeMinutes(); Run the task every three minutes
->everyFourMinutes(); Run the task every four minutes
->everyFiveMinutes(); Run the task every five minutes
->everyTenMinutes(); Run the task every ten minutes
->everyFifteenMinutes(); Run the task every fifteen minutes
->everyThirtyMinutes(); Run the task every thirty minutes
->hourly(); Run the task every hour
->hourlyAt(17); Run the task every hour at 17 minutes past the hour
->everyOddHour(); Run the task every odd hour
->everyTwoHours(); Run the task every two hours
->everyThreeHours(); Run the task every three hours
->everyFourHours(); Run the task every four hours
->everySixHours(); Run the task every six hours
->daily(); Run the task every day at midnight
->dailyAt('13:00'); Run the task every day at 13:00
->twiceDaily(1, 13); Run the task daily at 1:00 & 13:00
->twiceDailyAt(1, 13, 15); Run the task daily at 1:15 & 13:15
->weekly(); Run the task every Sunday at 00:00
->weeklyOn(1, '8:00'); Run the task every week on Monday at 8:00
->monthly(); Run the task on the first day of every month at 00:00
->monthlyOn(4, '15:00'); Run the task every month on the 4th at 15:00
->twiceMonthly(1, 16, '13:00'); Run the task monthly on the 1st and 16th at 13:00
->lastDayOfMonth('15:00'); Run the task on the last day of the month at 15:00
->quarterly(); Run the task on the first day of every quarter at 00:00
->quarterlyOn(4, '14:00'); Run the task every quarter on the 4th at 14:00
->yearly(); Run the task on the first day of every year at 00:00
->yearlyOn(6, 1, '17:00'); Run the task every year on June 1st at 17:00
->timezone('America/New_York'); Set the timezone for the task

Ngoài các tuỳ chọn trên bạn có thể kết hợp thêm các ràng buộc sau đây để tạo schedule chặt chẽ hơn :

Method Description
->weekdays(); Limit the task to weekdays
->weekends(); Limit the task to weekends
->sundays(); Limit the task to Sunday
->mondays(); Limit the task to Monday
->tuesdays(); Limit the task to Tuesday
->wednesdays(); Limit the task to Wednesday
->thursdays(); Limit the task to Thursday
->fridays(); Limit the task to Friday
->saturdays(); Limit the task to Saturday
->days(array - mixed); Limit the task to specific days
->between($startTime, $endTime); Limit the task to run between start and end times
->unlessBetween($startTime, $endTime); Limit the task to not run between start and end times
->when(Closure); Limit the task based on a truth test
->environments($env); Limit the task to specific environments

Ví dụ:

Lên lịch vào các ngày trong tuần : Chạy hàng giờ vào CN và T4

$schedule->command('emails:send') ->hourly() ->days([0, 3]);

Giữa 1 khoảng thời gian : Chạy hàng giờ trong khoảng thời gian từ 7:00 đến 22:00

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

Dựa vào điều kiện : Khi điều kiện đúng thì thực thi

$schedule->command('emails:send')->daily()->when(function () { return true;
});

Dựa vào môi trường

$schedule->command('emails:send') ->daily() ->environments(['staging', 'production']);

6. Ngăn việc chồng chéo task

Theo mặc định các task đã được lên lịch sẽ chạy mà không cần đợi task trước đó đã chạy xong hay chưa. Nên để ngăn việc đó bạn có thể sử dụng đến method withoutOverlapping:

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

Mặc định sẽ là sau 24h sau khi task trước đó kết thúc thì mới chạy đến task tiếp theo, nên bạn có thể khai báo thêm thời gian tuỳ chọn:

$schedule->command('emails:send')->withoutOverlapping(10);
  • Thưc chất việc này sử dụng đến cache để lưu biến lock. Đại loại như khi 1 task được chạy 1 biến lock sẽ được lưu vào cache, sau khi hoàn thành thì biến đó sẽ bị xoá đi. Nếu task tiếp theo chạy sẽ cần check biến lock đó có tồn tại hay không thì mới được chạy tiếp.
  • Nên nếu trường hợp có task nào đó bị kẹt thì bạn có thể xoá cache để khắc phục: schedule:clear-cache

Có thể vẫn chạy schedule cả khi ứng dụng trong maintenance mode : $schedule->command('emails:send')->evenInMaintenanceMode();

7. Chạy schedule

Môi trường server: để bắt đầu chạy schedule trên môi trường server bạn sử dụng lệnh với cú pháp như sau:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

image.png

Môi trường local : Chỉ cần chạy câu lệnh artisan sau:

php artisan schedule:work

Bình luận

Bài viết tương tự

- vừa được xem lúc

[Cron Job] - Tạo bot Slack nhắc nhở chạy bộ tập thể dục với Golang

Hà Nội, Chủ nhật, 21/08/2022... Vài lời gửi gắm thời gian. Nhạc sĩ : Trịnh Công Sơn. Hà Nội mùa thu, mùa thu Hà Nội. Mùa hoa sữa về thơm từng cơn gió.

0 0 34

- vừa được xem lúc

Chạy cronjob trong Docker container với Python

Trong quá trình phát triển, sẽ không thiếu những lúc mà chúng ta cần chạy định kỳ một vài script hoặc chạy một tác vụ nào đó vào thời gian nhất định. Những lúc như vậy thì Cron là một công cụ vô cùng

0 0 25

- vừa được xem lúc

SpringBoot - Schedule - Save Cronjob to DB - AOP

Spring-boot scheduled task manager with database. . Sử dụng springboot scheduled task để quản lý task và set thời gian cho từng task. Tạo thread mới khi run task.

0 0 12

- vừa được xem lúc

Hệ thống lớn sẽ quán lý Cron Job như thế nào ??? - Bài học thực tế từ Slack

Anh em đã biết đến Slack như là nền tảng làm việc hiện đại, nơi mọi người có thể giao tiếp, cộng tác và hoàn thành công việc một cách hiệu quả. Bằng cách kết hợp nhắn tin, công cụ và ứng dụng vào một

0 0 11

- vừa được xem lúc

Cơ bản về Redis, RabbitMQ, Bull, Bee-Queue, và cronjob

1. Kiến thức cơ bản về task management tools.

0 0 5

- vừa được xem lúc

Hệ thống lớn sẽ quản lý Cron Job như thế nào ??? - Video mô tả hệ thống Slack

Một trong các thành phần quan trọng trong thiết kế của Slack đó chính là các Cron Job. Các Cron job sẽ đảm nhiệm thực thi các tác vụ quan trọng tại Slack như lập lịch và tự động gửi email, thông báo t

0 0 10