Maison  >  Article  >  cadre php  >  Explication détaillée de l'utilisation et des principes des tâches planifiées de Laravel

Explication détaillée de l'utilisation et des principes des tâches planifiées de Laravel

WBOY
WBOYavant
2022-05-30 11:52:235586parcourir

Cet article vous apporte des connaissances pertinentes sur laravel. Il présente principalement l'utilisation et les principes des tâches planifiées. Il explique également les problèmes liés aux tâches planifiées en fonction des scénarios d'application. J'espère qu'il sera utile. tout le monde.

Explication détaillée de l'utilisation et des principes des tâches planifiées de Laravel

【Recommandations associées : tutoriel vidéo laravel

Scénarios d'application

Un système de site Web a souvent de nombreuses tâches planifiées à exécuter. Par exemple, les messages d'abonnement push, les données liées aux statistiques, etc. Linux utilise généralement crontab pour configurer et gérer les tâches planifiées. Cependant, à mesure que le nombre de tâches augmente, la gestion des tâches planifiées devient plus difficile et sujette à une confusion de gestion. La solution de Laravel à ce problème consiste à configurer une seule tâche planifiée.Toutes les tâches planifiées de l'entreprise sont traitées et jugées sur cette tâche planifiée, réalisant ainsi la gestion des tâches planifiées au niveau du code.

Utilisation de base

Configurez d'abord crontab :

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

Le moyen ci-dessus pour définir la tâche planifiée à exécuter toutes les minutes. La configuration métier spécifique est placée dans la méthode de planification d'AppConsoleKernel :

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

Analyse des principes :

Basique. Principe:
planning:run Cette spécification est définie dans la classe supplierilluminateconsoleSchedulingScheduleRunCommand. Le formulaire de définition est le même qu'une tâche planifiée générale :

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

Lorsque laravel analyse les commandes, la classe ScheduleRunCommand est fusionnée avec le tableau de commandes de la classe Kernel. :

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

Donc, la commande php artisan planning:run est une commande intégrée du framework.
Lorsque la commande est démarrée, elle utilisera par défaut la méthode handle de la classe pour l'exécution :

/** 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']);}

php artisan planning:run La commande analysera toutes les instructions enregistrées dans Kernel::schedule toutes les minutes et déterminera si l'instruction a atteint l'exécution. cycle , s'il arrive, placez-le dans la file d'attente pour être exécuté :

    /**
     * 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));
    }

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);
        }
    }

Éviter le chevauchement des tâches :
Parfois, le temps d'exécution d'une seule tâche planifiée est trop long après la suivante. temps d'exécution, le dernier La tâche d'exécution n'est pas encore terminée. À ce stade, nous pouvons utiliser la méthode withoutOverlapping() pour éviter le chevauchement des tâches. Dans la méthode withoutOverlapping, verrouillez la tâche correspondante (il en va de même pour la méthode onOneServer) :

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

Ce n'est que lorsque vous obtenez le verrouillage de la tâche correspondant que vous pourrez exécuter la tâche :

/**
     * 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);
    }

Tâche en cours d'exécution :
Depuis les tâches planifiées sont exécutés en séquence, le temps d'exécution de la tâche précédente est trop long, ce qui affectera le temps d'exécution de la tâche suivante, nous pouvons donc utiliser la méthode runInBackground pour mettre la tâche en arrière-plan pour l'exécution, ce qui est quelque peu similaire au rôle de & dans le shell :

/**
     * 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 &'
        );
    }

Autres utilisations :

Sauf Dans la méthode ci-dessus, nous pouvons également utiliser les tâches planifiées de Laravel pour appeler des commandes Shell :

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

Vous pouvez également utiliser des fermetures pour la planification :

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

Si vous le souhaitez pour en savoir plus sur son utilisation, vous pouvez consulter la documentation de Laravel :

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

[Recommandations associées : tutoriel vidéo laravel]

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer