Planification des tâches
- Définir le planning
- Artis une planification des commandes
- Planification des commandes Shell
- Paramètre de la fréquence de planification
- Limite de plage horaire
- Limite du test de fermeture
- Contraintes environnementales
- Tâche d'arrière-plan Mode de maintenancePlanification des tâches
- Paramètres de fréquence de planification
- Fuseau horaire
-
- Évitez la duplication des tâches
- Les tâches ne s'exécutent que sur un seul serveur
- Tâches en arrière-plan
- Mode maintenance
- Sortie des tâches
- Crochet de tâche
- Introduction
- Dans le passé, vous devrez peut-être créer une entrée Cron pour chaque tâche planifiée sur le serveur. Mais cette approche devient vite peu conviviale car ces planificateurs de tâches ne sont pas dans le code source et vous devez à chaque fois vous connecter au serveur via un lien SSH pour ajouter une entrée Cron. Le planificateur de ligne de commande Laravel vous permet de définir clairement et en douceur la planification des commandes dans Laravel. Et lorsque vous utilisez ce planificateur de tâches, il vous suffit de créer une seule interface d'entrée Cron sur votre serveur. Votre planning de tâches est défini dans la méthode
schedule
deapp/Console/Kernel.php
. Pour vous aider à démarrer, voici un exemple simple de cette méthode.Démarrez le planificateur
- Lorsque vous utilisez ce planificateur, il vous suffit d'ajouter l'entrée Cron suivante à votre serveur Can. Si vous ne savez pas comment ajouter une entrée Cron au serveur, vous pouvez envisager d'utiliser certains services pour gérer les entrées Cron, tels que Laravel Forge :
Ce Cron est un planificateur de ligne de commande qui exécute Laravel toutes les minutes. Lorsque la commande* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
schedule:run
est exécutée, Laravel exécutera le programme planifié selon votre planning.Définir les horairesVous pouvez le faire dans la classe
AppConsoleKernel
Toutes les tâches de planification sont définies dans la méthode >schedule. Avant de commencer, regardons un exemple. Dans cet exemple, nous prévoyons d'appeler une fermeture tous les jours à minuit. Dans une fermeture, nous exécutons une requête de base de données pour effacer une table :<?php namespace App\Console; use Illuminate\Support\Facades\DB; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel{ /** * 应用里的自定义 Artisan 命令 * * @var array */ protected $commands = [ // ]; /** * 定义计划任务 * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { $schedule->call(function () { DB::table('recent_users')->delete(); })->daily(); } }
En plus d'utiliser des fermetures pour définir des plannings de tâches, vous pouvez également utiliser desobjets invocables.
$schedule->call(new DeleteRecentUsers)->daily();
app/Console/Kernel.php
的schedule
方法中进行定义。为了帮助你更好的入门,这个方法中有个简单的例子。启动调度器
当使用这个调度器时,你只需要把下面的 Cron 入口添加到你的服务器中即可。如果你不知道怎么在服务器中添加 Cron 入口,可以考虑使用一些服务来管理 Cron 入口,比如 Laravel Forge:
$schedule->command('emails:send --force')->daily(); $schedule->command(EmailsCommand::class, ['--force'])->daily();
这个 Cron 为每分钟执行一次 Laravel 的命令行调度器。当
schedule:run
命令被执行的时候,Laravel 会根据你的调度执行预定的程序。定义调度
你可以在
AppConsoleKernel
类的schedule
Planification des commandes Artisan
En plus de la planification en appelant des fermetures, vous pouvez également appeler des commandes Artisan et des commandes du système d'exploitation. Par exemple, vous pouvez envoyer une commande Artisan en transmettant le nom ou la classe de la commande à la méthode
command
.command
方法传递命令名称或者类来调度一个 Artisan 命令。$schedule->job(new Heartbeat)->everyFiveMinutes(); // 分发任务到「heartbeats」队列... $schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();
队列任务调度
job
方法可以用来调度 队列任务。此方法提供了一种快捷的方式来调度任务,而无需使用call
方法创建闭包来调度任务。$schedule->exec('node /home/forge/script.js')->daily();
Shell 命令调度
exec
// 每周一 13:00 执行... $schedule->call(function () { // })->weekly()->mondays()->at('13:00'); // 工作日(周一至周五) 8点 至 17 点每小时执行一次... $schedule->command('foo') ->weekdays() ->hourly() ->timezone('America/Chicago') ->between('8:00', '17:00');
La planification des tâches en file d'attenteLa méthodejob
peut être utilisé pour planifier les tâches de file d'attente. Cette méthode fournit un moyen rapide de planifier des tâches sans avoir à créer une fermeture à l'aide de la méthodecall
pour planifier des tâches. 🎜$schedule->command('reminders:send') ->hourly() ->between('7:00', '22:00');
🎜🎜🎜🎜🎜La méthode de planification des commandes Shell🎜🎜exec
peut être utilisé Envoyer des commandes au système d'exploitation : 🎜$schedule->command('reminders:send') ->hourly() ->unlessBetween('23:00', '4:00');
🎜🎜🎜🎜🎜🎜Paramètres de fréquence de planification
Bien sûr, vous pouvez attribuer plusieurs plans de planification à vos tâches :
🎜 Exécuter une tâche à 15h00 le 4 de chaque mois🎜🎜🎜🎜Méthode Description ->cron('* * * * *');
->cron('* * * * *');
自定义 Cron 时间表执行任务 ->everyMinute();
每分钟执行一次任务 ->everyFiveMinutes();
每五分钟执行一次任务 ->everyTenMinutes();
每十分钟执行一次任务 ->everyFifteenMinutes();
每十五分钟执行一次任务 ->everyThirtyMinutes();
每三十分钟执行一次任务 ->hourly();
每小时执行一次任务 ->hourlyAt(17);
每小时第 17 分钟执行一次任务 ->daily();
每天午夜执行一次任务(译者注:每天零点) ->dailyAt('13:00');
每天 13 点执行一次任务 ->twiceDaily(1, 13);
每天 1 点 和 13 点分别执行一次任务 ->weekly();
每周执行一次任务 🎜 Tâche d'exécution de planification Cron personnalisée->weeklyOn(1, '8:00');
- >everyMinute();
🎜🎜Exécuter une tâche toutes les minutes🎜🎜🎜🎜->everyFiveMinutes();
🎜🎜Exécuter une tâche toutes les cinq minutes🎜🎜🎜🎜< code> ->everyTenMinutes();🎜🎜Exécuter une tâche toutes les dix minutes🎜🎜🎜🎜->everyFifteenMinutes();
🎜🎜Exécuter une tâche toutes les quinze minutes🎜🎜 🎜🎜< code>->everyThirtyMinutes();🎜🎜Exécuter une tâche toutes les trente minutes🎜🎜🎜🎜->hourly();
🎜🎜Exécuter une tâche toutes les heures 🎜🎜🎜🎜->hourlyAt(17);
🎜🎜Exécuter la tâche à la 17ème minute toutes les heures🎜🎜🎜🎜->daily();
🎜🎜Chaque jour Exécuter un tâche à minuit (Note du traducteur : zéro heure tous les jours)🎜🎜🎜🎜->dailyAt('13:00');
🎜🎜Exécuter une tâche à 13h00 tous les jours🎜🎜 🎜🎜->twiceDaily(1, 13);
🎜🎜Exécuter des tâches une fois par jour à 1h00 et 13h00🎜🎜🎜🎜->hebdomadaire(); code>🎜🎜Exécuter une tâche une fois par semaine🎜🎜🎜🎜
->weeklyOn(1, '8:00');
🎜🎜Exécuter la tâche tous les lundis à 8 heures🎜🎜->monthly();
->monthly();
每月执行一次任务 ->monthlyOn(4, '15:00');
每月 4 号的 15 点执行一次任务 ->quarterly();
每季度执行一次任务 ->yearly();
每年执行一次任务 Exécuter la tâche une fois par mois->timezone('America/New_York');
->monthlyOn(4, '15:00');
->trimestriel();
🎜🎜Exécuter une tâche tous les trimestres🎜🎜🎜🎜->annuel ();< /code>🎜🎜Exécuter la tâche une fois par an🎜🎜🎜🎜
🎜🎜Limiter les tâches à exécuter le jeudi🎜🎜🎜🎜->timezone('America/New_York');
🎜🎜Définir le fuseau horaire🎜🎜🎜🎜En combinaison avec d'autres conditions spécifiques, nous pouvons générer des tâches qui s'exécutent à des moments précis de la semaine. Par exemple, pour exécuter la commande tous les lundis :
$schedule->command('emails:send')->daily()->when(function () { return true; });
La liste des contraintes supplémentaires est la suivante :
🎜Limiter les tâches à exécuter le week-end🎜🎜🎜🎜Méthode Description ->weekdays();
->weekdays();
限制任务在工作日执行 ->weekends();
限制任务在周末执行 ->sundays();
限制任务在周日执行 ->mondays();
限制任务在周一执行 ->tuesdays();
限制任务在周二执行 ->wednesdays();
限制任务在周三执行 ->thursdays();
限制任务在周四执行 ->fridays();
限制任务在周五执行 ->saturdays();
限制任务在周六执行 ->between($start, $end);
限制任务在 $start
和$end
之间执行->when(Closure);
当闭包返回为真时执行 Limiter les tâches à exécuter en semaine->environments($env);
->week-ends();
->dimanche() ;
🎜🎜Limiter les tâches à exécuter le dimanche🎜🎜🎜🎜->lundi();
🎜🎜Limiter les tâches à exécuter le lundi🎜🎜🎜🎜-> ;mardi();
🎜🎜Limiter les tâches à exécuter le mardi🎜🎜🎜🎜->mercredi();
🎜🎜Limiter les tâches à exécuter le mercredi🎜🎜🎜🎜< code>->jeudi();->vendredi();
🎜🎜Limiter les tâches à exécuter le vendredi🎜 🎜🎜🎜->samedi();< /code>🎜🎜Limiter les tâches à exécuter le samedi🎜🎜🎜🎜
->entre ($start, $end);
🎜 🎜Limiter les tâches à exécuter entre$start
et$end
Exécuté entre 🎜🎜🎜🎜->when(Closure);
🎜🎜Exécuté lorsque la fermeture renvoie true🎜🎜🎜🎜-> environnements ($env);
🎜🎜Restreindre les tâches à exécuter dans des environnements spécifiques🎜🎜🎜🎜Restriction de plage horaire
Utilisez
between
pour limiter la tâche à une certaine période de la journée :between
来限制任务在一天中的某个时间段来执行:$schedule->command('emails:send')->daily()->skip(function () { return true; });
或者使用
unlessBetween
方法来为任务排除一个时间段:$schedule->command('emails:send') ->daily() ->environments(['staging', 'production']);
闭包测试限制
使用
when
方法来根据测试结果来执行任务。也就是说,如果给定的闭包返回结果为true
,只要没有其他约束条件阻止任务运行,任务就会一直执行下去:$schedule->command('report:generate') ->timezone('America/New_York') ->at('02:00')
skip
方法可以看做是when
方法的逆过程。如果skip
方法返回true
,任务就不会执行:/** * 获取默认情况下应为预定事件使用的时区。 * * @return \DateTimeZone|string|null */ protected function scheduleTimezone(){ return 'America/Chicago'; }
使用链式调用
when
方法时,只有所有的when
都返回true
时,任务才会执行。环境约束
environments
方法可用于仅在给定环境中执行任务:$schedule->command('emails:send')->withoutOverlapping();
时区
使用
timezone
方法,你可以指定任务在给定的时区内执行:$schedule->command('emails:send')->withoutOverlapping(10);
如果要为所有计划任务分配相同的时区,则可能希望在
app/Console/Kernel.php
文件中定义scheduleTimezone
方法。 此方法应返回应分配给所有计划任务的默认时区:$schedule->command('report:generate') ->fridays() ->at('17:00') ->onOneServer();
{note} 请记住,有些时区会使用夏令时。当夏时制时间发生更改时,你的任务可能会执行两次,甚至根本不会执行。所以我们建议尽可能避免使用时区来安排计划任务。
避免任务重复
默认情况下,即使之前的任务还在执行,调度内任务也会执行。你可以使用
withoutOverlapping
方法来避免这种情况:$schedule->command('analytics:report') ->daily() ->runInBackground();
在这个例子中,如果
emails:send
Artisan 命令 没有正在运行,它将会每分钟执行一次。如果你的任务执行时间不确定,且你又不能准确预估出任务的执行时间,那么withoutOverlapping
$schedule->command('emails:send')->evenInMaintenanceMode();
ou utilisez la méthodesauf entre
pour exclure une tâche Heure Période :$schedule->command('emails:send') ->daily() ->sendOutputTo($filePath);
Limites du test de fermetureUtilisez la méthode
when
pour effectuer des tâches basées sur les résultats des tests. C'est-à-dire que si la fermeture donnée renvoietrue
, la tâche continuera à s'exécuter tant qu'il n'y aura pas d'autres contraintes qui empêchent la tâche de s'exécuter :$schedule->command('emails:send') ->daily() ->appendOutputTo($filePath);
skip
méthode Cela peut être vu comme le processus inverse de la méthodewhen
. Si la méthodeskip
renvoietrue
, la tâche ne sera pas exécutée :$schedule->command('foo') ->daily() ->sendOutputTo($filePath) ->emailOutputTo('foo@example.com');
🎜Lors de l'appel de la méthodewhen
dans une chaîne, uniquement tous les < code> Lorsque renvoient tous deuxtrue
, la tâche sera exécutée. La méthode 🎜🎜🎜Contraintes d'environnement🎜🎜environnements
peut être utilisée pour effectuer des tâches uniquement dans un environnement donné : 🎜$schedule->command('emails:send') ->daily() ->before(function () { // Task is about to start... }) ->after(function () { // Task is complete... });
🎜🎜🎜🎜Timezone
🎜En utilisant la méthodetimezone
, vous pouvez spécifier que la tâche est dans un fuseau horaire donné Exécution dans : 🎜$schedule->command('emails:send') ->daily() ->pingBefore($url) ->thenPing($url);
🎜 Si vous souhaitez attribuer le même fuseau horaire à toutes les tâches planifiées, vous souhaiterez peut-être définir la méthodescheduleTimezone
dans le fichierapp/Console/Kernel Fichier .php
. Cette méthode doit renvoyer le fuseau horaire par défaut qui doit être attribué à toutes les tâches planifiées : 🎜$schedule->command('emails:send') ->daily() ->pingBeforeIf($condition, $url) ->thenPingIf($condition, $url);
🎜{note} Gardez à l'esprit que certains fuseaux horaires utilisent l'heure d'été. Lorsque l’heure d’été change, votre tâche peut s’exécuter deux fois, voire pas du tout. Nous recommandons donc d’éviter autant que possible d’utiliser les fuseaux horaires pour planifier les tâches planifiées. 🎜
🎜🎜🎜🎜Prévenir la duplication de tâches
🎜Par défaut, même si la tâche précédente est toujours en cours d'exécution, les tâches planifiées seront exécutées. Vous pouvez éviter cela en utilisant la méthodewithoutOverlapping
: 🎜composer require guzzlehttp/guzzle
🎜Dans cet exemple, si la commandeemails:send
Artisan n'est pas en cours d'exécution, elle sera exécutée toutes les minutes. La méthodewithoutOverlapping
est particulièrement utile si le temps d'exécution de votre tâche est incertain et que vous ne pouvez pas estimer avec précision le temps d'exécution de la tâche. 🎜🎜Si nécessaire, vous pouvez spécifier "sans chevauchement" pour verrouiller la plage horaire spécifiée. Par défaut, les verrous expirent après 24 heures. 🎜rrreee🎜🎜🎜🎜🎜🎜La tâche ne s'exécute que sur un seul serveur
{note} Pour utiliser cette fonctionnalité, le pilote de cache par défaut de votre application doit être
memcached
ouredis
. De plus, tous les serveurs doivent communiquer en utilisant le même serveur de cache central.memcached
或者redis
。除此之外,所有的服务器必须使用同一个中央缓存服务器通信。如果你的应用在多个服务器上运行,你可能需要限制你的调度任务只在单个服务器上运行。假设你有一个调度任务:每周五晚生成一份新报告。如果这个任务调度器在三个服务器上运行,那么这个任务会在三台服务器上运行且生成三份报告。这样不好!
为了说明任务应该在单个服务器上运行,在定义调度任务时使用
rrreeeonOneServer
方法。第一个获取到任务的服务器会生成一个原子锁,用来防止其他服务器在同一时刻执行相同任务。后台任务
默认情况下,同时调度的多个命令将按顺序执行。如果你有长时间运行的命令,这可能会导致后续命令的启动时间比预期的要晚。因此,你想在后台同时运行命令,可以使用
rrreeerunInBackground
方法:维护模式
Laravel 的队列任务在 维护模式 下不会运行。因为我们不想你的调度任务干扰到你服务器上可能还未完成的项目。不过,如果你确实是想在维护模式下强制调度任务执行,你可以使用
rrreeeevenInMaintenanceMode
方法:任务输出
Laravel 调度器提供了一些方便的方法来处理调度任务输出。首先,你可以使用
rrreeesendOutputTo
方法来输出到文件以便于后续检查:如果希望将输出
rrreee附加
到给定文件,可以使用appendOutputTo
方法使用
rrreeeemailOutputTo
方法,你可以将输出发送到指定邮箱。在使用邮件发送之前,你需要配置 Laravel 的 邮件服务:{note}
emailOutputTo
,sendOutputTo
和appendOutputTo
方法是command
和exec
独有的。任务钩子
使用
Si votre application s'exécute sur plusieurs serveurs, vous souhaiterez peut-être limiter vos tâches planifiées pour qu'elles s'exécutent uniquement sur un seul serveur. Supposons que vous disposiez d'un planning qui génère un nouveau rapport chaque vendredi soir. Si le planificateur de tâches s'exécute sur trois serveurs, la tâche s'exécutera sur trois serveurs et générera trois rapports. Ce n'est pas bon ! Pour indiquer que la tâche doit s'exécuter sur un seul serveur, utilisez la méthodebefore
和after
onOneServer
lors de la définition de la tâche planifiée. Le premier serveur à obtenir la tâche générera un verrou atomique pour empêcher d'autres serveurs d'exécuter la même tâche en même temps. 🎜rrreee🎜🎜🎜🎜Tâches en arrière-plan🎜🎜Par défaut, plusieurs commandes planifiées simultanément s'exécuteront dans l'ordre . Si vos commandes s'exécutent depuis longtemps, les commandes suivantes peuvent démarrer plus tard que prévu. Par conséquent, si vous souhaitez exécuter des commandes en arrière-plan en même temps, vous pouvez utiliser la méthoderunInBackground
: 🎜rrreee🎜🎜🎜🎜Mode maintenance🎜🎜Les tâches de file d'attente de Laravel ne s'exécuteront pas en mode maintenance. Parce que nous ne voulons pas que vos tâches de planification interfèrent avec des projets qui pourraient ne pas être terminés sur votre serveur. Cependant, si vous souhaitez vraiment forcer l'exécution de tâches planifiées en mode maintenance, vous pouvez utiliser la méthodeevenInMaintenanceMode
: 🎜rrreee🎜🎜🎜Sortie de tâche
🎜Le planificateur Laravel fournit des méthodes pratiques pour gérer la sortie de tâche planifiée. Tout d'abord, vous pouvez utiliser la méthodesendOutputTo
pour sortir dans un fichier pour une inspection ultérieure : 🎜rrreee🎜 Si vous souhaitezajouter
la sortie à un fichier donné, vous pouvez utiliser < Méthode code>appendOutputTo< /code> 🎜rrreee🎜En utilisant la méthodeemailOutputTo
, vous pouvez envoyer la sortie à la boîte aux lettres spécifiée. Avant d'utiliser le courrier électronique pour envoyer, vous devez configurer le service de messagerie de Laravel : 🎜rrreee🎜🎜{note} Les méthodesemailOutputTo
,sendOutputTo
etappendOutputTo
sont < Unique à code>command etexec
. 🎜🎜🎜🎜. 🎜🎜Hooks de tâches
🎜Utilisezavant
etaprès
, vous pouvez exécuter du code spécifique avant ou après l'exécution de la tâche planifiée : 🎜rrreee🎜🎜Ping URL
À l'aide des méthodes
rrreeepingBefore
etthenPing
, vous pouvez pinger l'URL spécifiée avant ou après l'exécution de la tâche. Cette méthode sera particulièrement utile lors de la notification de services externes (tels que Laravel EnvoyerpingBefore
和thenPing
方法,你可以在任务执行前或者执行后来 ping 指定的 URL。这个方法在通知外部服务(比如 Laravel Envoyer)时将会特别有用:只有在给定条件为
rrreeetrue
时,才能使用pingBeforeIf
和thenPingIf
) :Seulement si donné Seulement lorsque la condition est
rrreeetrue
, pouvez-vous utiliser les méthodespingBeforeIf
etthenPingIf
pour pinger l'URL spécifiée :Toutes les méthodes ping nécessitent le HTTP Guzzle bibliothèque. Vous pouvez utiliser Composer pour ajouter Guzzle à votre projet : rrreeeCet article est apparu pour la première fois sur le site WebLearnKu.com