Home > PHP Framework > Laravel > body text

Detailed explanation of laravel scheduled task usage and principles

WBOY
Release: 2022-05-30 20:51:11
forward
5592 people have browsed it

This article brings you relevant knowledge about laravel, which mainly introduces the usage and principles of scheduled tasks. It also explains the related issues of scheduled tasks according to the application scenarios. Below Let's take a look, I hope it will be helpful to everyone.

Detailed explanation of laravel scheduled task usage and principles

[Related recommendations: laravel video tutorial]

Application scenarios

A website system often has many Scheduled tasks need to be executed. For example, push subscription messages, statistics related data, etc. Linux generally uses crontab to set up and manage scheduled tasks. However, as the number of tasks increases, managing scheduled tasks becomes more troublesome and prone to management confusion. Laravel's solution to this problem is to set up only one scheduled task. All scheduled tasks in the business are processed and judged on this scheduled task, realizing the management of scheduled tasks at the code level.

Basic usage

First configure crontab:

* * * * * php artisan schedule:run >> /dev/null 2>&1
Copy after login

The above means to set the scheduled task to be executed every minute. The specific business configuration is placed in App\Console\Kernel In the schedule method:

class Kernel extends ConsoleKernel{
    Protected function schedule(Schedule $schedule)
    {
                //综合数据统计
        $schedule->command('complex_data_log')
        ->everyMinute() //每分钟执行一次(除此之外还有,每五、十、十五、三十...,不同方法设置的默认时间不同)
        ->withoutOverlapping() //防止重复执行
        ->onOneServer() //在单台服务器上跑
        ->runInBackground() //任务后台运行
        //->appendOutputTo('log_path')//日志输出,默认追加
        ->sendOutputTo('log_path'); //日志输出,默认覆盖先前日志
    }}
Copy after login

Principle analysis:

Basic principle:
schedule:run This specification is in the vendor\illuminate\console\Scheduling\ScheduleRunCommand class It is defined inside, and the definition form is the same as the general scheduled task:

/**
 * The console command name.
 *
 * @var string
 */protected $name = 'schedule:run';
Copy after login

When laravel parses the command, the ScheduleRunCommand class is merged with the commands array in the Kernel class:

	/**
     * Get the commands to add to the application.
     *
     * @return array
     */
    protected function getCommands()
    {
        return array_merge($this->commands, [
            'Illuminate\Console\Scheduling\ScheduleRunCommand',
        ]);
    }
Copy after login

So the php artisan schedule:run command is a built-in command of the framework.
When the command is started, it will find the handle method in the class by default for execution:

/** vendor\illuminate\console\Command.php
 * Execute the console command.
 * 
 * @param  \Symfony\Component\Console\Input\InputInterface  $input
 * @param  \Symfony\Component\Console\Output\OutputInterface  $output
 * @return mixed
 */protected function execute(InputInterface $input, OutputInterface $output){
    return $this->laravel->call([$this, 'handle']);}
Copy after login

php The artisan schedule:run command will scan all instructions registered in Kernel::schedule every minute and determine the Whether the instruction has reached the execution cycle, if so, push it into the queue to be executed:

    /**
     * Schedule the event to run every minute.
     * 代码每分钟执行一次
     * @return $this
     */
    public function everyMinute()
    {
        return $this->spliceIntoPosition(1, '*');
    }
    
    /**
     * Splice the given value into the given position of the expression.
     * 拼接定时任务表达式
     * @param  int  $position
     * @param  string  $value
     * @return $this
     */
    protected function spliceIntoPosition($position, $value)
    {
        $segments = explode(' ', $this->expression);

        $segments[$position - 1] = $value;

        return $this->cron(implode(' ', $segments));
    }
Copy after login

ScheduleRunCommand::handle function:

/**
     * Execute the console command.
     * 
     * @return void
     */
    public function handle()
    {
        foreach ($this->schedule->dueEvents($this->laravel) as $event) {
            if (! $event->filtersPass($this->laravel)) {
                continue;
            }
            $this->runEvent($event);
        }
    }
Copy after login

Avoid task overlap:
Sometimes the execution time of a single scheduled task is too long. After the next execution time, the last execution task has not been completed. At this time, we can use the withoutOverlapping() method to avoid task overlap. In the withoutOverlapping method, lock the corresponding task (the same is true for the onOneServer method):

public function create(Event $event){
    return $this->cache->store($this->store)->add(
        $event->mutexName(), true, $event->expiresAt
    );}
Copy after login

Only when the corresponding task lock is obtained can the task be executed:

/**
     * Run the given event.
     * 运行任务
     * @param  \Illuminate\Contracts\Container\Container  $container
     * @return void
     */
    public function run(Container $container)
    {
        if ($this->withoutOverlapping &&
            ! $this->mutex->create($this)) {
            return;
        }
        
        //判断是否是后台运行
        $this->runInBackground
                    ? $this->runCommandInBackground($container)
                    : $this->runCommandInForeground($container);
    }
Copy after login

The task runs in the background :
Since scheduled tasks are executed in sequence, the execution time of the previous task is too long, which will affect the execution time of the next task. Therefore, we can use the runInBackground method to execute the task in the background, which is somewhat similar to a shell. The role of &:

/**
     * Build the command for running the event in the background.
     * 构建定时任务后台运行语句
     * @param  \Illuminate\Console\Scheduling\Event  $event
     * @return string
     */
    protected function buildBackgroundCommand(Event $event)
    {
        $output = ProcessUtils::escapeArgument($event->output);

        $redirect = $event->shouldAppendOutput ? ' >> ' : ' > ';

        $finished = Application::formatCommandString('schedule:finish').' "'.$event->mutexName().'"';

        return $this->ensureCorrectUser($event,
            '('.$event->command.$redirect.$output.' 2>&1 '.(windows_os() ? '&' : ';').' '.$finished.') > '
            .ProcessUtils::escapeArgument($event->getDefaultOutput()).' 2>&1 &'
        );
    }
Copy after login

Other uses:

In addition to the above method, we can also use laravel's scheduled tasks to call Shell commands:

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

You can also use closure Package scheduling:

$schedule->call(function () {
    DB::table('recent_users')->delete();})->daily();
Copy after login

If you want to know more about how to use it, you can check laravel’s documentation:

https://laravelacademy.org/post/19517.html

[Related recommendations: laravel video tutorial]

The above is the detailed content of Detailed explanation of laravel scheduled task usage and principles. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:csdn.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template