Implementation of Timed Task Scheduling in Laravel


brief introduction

Cron is a very useful tool under UNIX, SOLARIS, and LINUX. Cron script enables scheduled tasks to run automatically in the system background on a regular basis. This kind of planned task is called Cron Jobs under UNIX, SOLARIS and LINUX. Crontab is a script file used to record Cron running at a specific time. Each line of Crontab file follows a specific format:

We can use the crontab -e To add or edit Cron entries, click crontab -l View existing Cron entries. For more details about the principle and use of Cron, please go to Baidu or Google.

In the past, developers needed to write a Cron entry for each task to be scheduled, which was a headache. Your task scheduling is not under source control. You must use SSH to log in to the server and add these Cron entries.

Laravel command scheduler allows you to define command scheduling in Laravel in a streaming and elegant manner, and only one Cron entry is required on the server. Task scheduling is defined in app/Console/Kernel.php Filed schedule Method, which already contains an example.

Turn on the scheduler

The following is the only Cron entry you need to add to the server. If you don't know how to add Cron entries to the server, you can consider using Laravel Forge This service is used to manage Cron entries:

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

The Cron will call the Laravel command scheduler every minute, and then Laravel will evaluate your scheduled tasks and run the expired tasks.

Define Schedule

You can App\Console\Kernel Class schedule All scheduling tasks are defined in the method. Let's start with an example of scheduling tasks. In this example, we will schedule a called closure at midnight every day. In this closure, we will perform a database operation to empty the table:

 <? php namespace App\Console; use DB; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel{ /** *Apply the Artisan commands provided *  * @var array */ protected $commands = [ //  ]; /** *Define applied command scheduling * * @param  \Illuminate\Console\Scheduling\Schedule  $schedule * @return void * @translator laravelacademy.org */ protected function schedule(Schedule $schedule) { $schedule->call(function () { DB::table('recent_users')->delete(); })->daily(); } }

Scheduling Artisan Commands

In addition to scheduling closure calls, you can also schedule Artisan Command And operating system commands. For example, you can use command Method to schedule an Artisan command by command name or class:

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

Scheduling Queue Tasks

job Method can be used to schedule a Queue Task , this method can easily schedule tasks without calling call Method Manually create closed packets to push tasks to the queue:

 $schedule->job(new Heartbeat)->everyFiveMinutes();

Scheduling Shell Commands

exec Method can be used to invoke operating system commands:

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

Scheduling Common Options

Of course, you can assign multiple scheduling tasks:
method describe
->cron('* * * * *'); Run tasks on custom Cron schedules
->everyMinute(); Run the task every minute
->everyFiveMinutes(); Run the task every five minutes
->everyTenMinutes(); Run the task every ten minutes
->everyFifteenMinutes(); Run the task every 15 minutes
->everyThirtyMinutes(); Run the task every 30 minutes
->hourly(); Run task every hour
->hourlyAt(17); Run the task every hour in the 17th minute
->daily(); Run the task at midnight every day
->dailyAt('13:00'); Run the task at 13:00 every day
->twiceDaily(1, 13); Run tasks at 1:00&13:00 every day
->weekly(); Run task once a week
->monthly(); Run the task once a month
->monthlyOn(4, '15:00'); Run the task at 15:00 on the 4th of every month
->quarterly(); Run quarterly
->yearly(); Run once a year
->timezone('America/New_York'); Set Time Zone

These methods can be combined with additional constraints to create a more fine-grained schedule that runs at a specific time of the week. For example, to schedule a command every Monday:

 $schedule->call(function () { //Run every Monday at 13:00 })->weekly()->mondays()->at('13:00'); //Run hourly from 8am to 5pm on weekdays $schedule->command('foo') ->weekdays() ->hourly() ->timezone('America/Chicago') ->between('8:00', '17:00');

The following is a list of additional scheduling constraints:

method describe
->weekdays(); Only run tasks on weekdays
->sundays(); Run tasks every Sunday
->mondays(); Run the task every Monday
->tuesdays(); Run the task every Tuesday
->wednesdays(); Run the task every Wednesday
->thursdays(); Run the task every Thursday
->fridays(); Run the task every Friday
->saturdays(); Run the task every Saturday
->between($start, $end); Run tasks based on a specific time period
->when(Closure); Run tasks based on specific tests
Constraints between time

between The method is used to limit task execution in a specific time period of a day:

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

Similarly, unlessBetween Method is used to exclude the execution of tasks in a specified time period:

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

Constraints of truth testing

when Method is used to restrict task execution based on the results of a given truth test. In other words, if a given closure returns true , as long as there are no other constraints preventing the task from running, the task will execute:

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

skip Methods and when Conversely, if skip Method return true , the scheduling task will not execute:

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

use when When the method chain is used, the scheduling command will only execute and return true Of when method.

Avoid overlapping tasks

By default, the scheduled task will run even if the previous task is still running. To avoid this situation, you can use withoutOverlapping method:

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

In this example, Artisan Command emails:send It will run every minute if the command is not running. If your tasks often change significantly in execution, then withoutOverlapping The method is very useful. You don't have to predict how long a given task will take.

If necessary, you can specify the number of minutes before the "without overlapping" lock expires. By default, the lock will expire 24 hours later:

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

maintenance mode

When Larravel is in maintenance mode The scheduled task will not run during maintenance mode. However, if you want to force the task to run during maintenance mode, you can use evenInMaintenanceMode method:

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

Task output

Laravel scheduler provides several convenient methods for processing scheduling task output. First, use the sendOutputTo Method, you can send the output to a file to check later:

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

If you want to append output to a given file, you can use appendOutputTo method:

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

use emailOutputTo Method, you can send the output to the recipient by email. Before using email to send task output, you need to configure Larave's mail serve

 $schedule->command('foo') ->daily() ->sendOutputTo($filePath) ->emailOutputTo(' foo@example.com ');
Note: emailOutputTo sendOutputTo and appendOutputTo Method only applies to command The method is valid and not supported call method.

Task Hooks

use before and after Method, you can specify the code to be executed before and after the scheduled task is completed:

 $schedule->command('emails:send') ->daily() ->before(function () { //The task is about to start }) ->after(function () { //Task completed });

Ping URL

use pingBefore and thenPing Method, the scheduler can ping the given URL automatically before and after the task is completed. This method is useful for notifying external services, such as Laravel Envoyer , when the scheduled task starts or finishes:

 $schedule->command('emails:send') ->daily() ->pingBefore($url) ->thenPing($url);

use pingBefore($url) or thenPing($url) For features, you need to install HTTP library Guzzle. You can use Composer package manager to install Guzzle depending on the project:

 composer require guzzlehttp/guzzle

give the thumbs-up Cancel Like Collection Cancel Collection

<<Previous: Development and use of Laravel custom expansion package

>>Next: Quick start: integrate PHPUnit to write test cases