- Introduction
- Définition des planifications
- Planification des commandes Artisan
- Planification des tâches en file d’attente
- Planification des commandes Shell
- Options de fréquence de planification
- Tones horaires
- Prévenir les chevauchements de tâches
- Exécution de tâches sur un serveur
- Tâches d’arrière-plan
- Mode maintenance
.
- Exécution du planificateur
- Exécution du planificateur localement
- Sortie de tâche
- Crochets de tâche
- Introduction
- Définir les planifications
- Planification des commandes Artisan
- Planification de travaux en file d’attente
- Commandes Shell de planification
- Options de fréquence de planification
- Contraintes de jour
- Contraintes d’intervalle de temps
- Contraintes de test de vérité
- Contraintes d’environnement
- Timezones
- Prévenir les chevauchements de tâches
- Exécution de tâches sur un seul serveur
- Tâches d’arrière-plan
- Mode maintenance
- Exécution du planificateur
- Exécuter l’ordonnanceur localement
- Sortie de la tâche
- Crochets de tâche
- Pinging d’URL
Introduction
Dans le passé, vous avez peut-être écrit une entrée de configuration cron pour chaque tâche que vous deviez planifier sur votre serveur. Cependant, cela peut rapidement devenir une douleur parce que votre planification des tâches n’est plus dans le contrôle de la source et vous devez SSH dans votre serveur pour voir vos entrées cron existantes ou ajouter des entrées supplémentaires.
Le planificateur de commande de Laravelle offre une approche nouvelle de la gestion des tâches planifiées sur votre serveur. Le planificateur vous permet de définir de manière fluide et expressive votre planification de commande au sein même de votre application Laravel. Lorsque vous utilisez le planificateur, une seule entrée cron est nécessaire sur votre serveur. La planification de vos tâches est définie dans la méthode schedule
du fichier app/Console/Kernel.php
. Pour vous aider à démarrer, un exemple simple est défini dans la méthode.
Définir les planifications
Vous pouvez définir toutes vos tâches planifiées dans la méthode schedule
de la classe App\Console\Kernel
de votre application. Pour commencer, jetons un coup d’œil à un exemple. Dans cet exemple, nous allons programmer une fermeture qui sera appelée tous les jours à minuit. Dans la fermeture, nous exécuterons une requête de base de données pour effacer une table:
<?phpnamespace App\Console;use Illuminate\Console\Scheduling\Schedule;use Illuminate\Foundation\Console\Kernel as ConsoleKernel;use Illuminate\Support\Facades\DB;class Kernel extends ConsoleKernel{ /** * The Artisan commands provided by your application. * * @var array */ protected $commands = ; /** * 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(); }}
En plus de la planification à l’aide de fermetures, vous pouvez également planifier des objets invocables. Les objets invocables sont des classes PHP simples qui contiennent une méthode __invoke
:
$schedule->call(new DeleteRecentUsers)->daily();
Si vous souhaitez afficher une vue d’ensemble de vos tâches planifiées et de leur prochaine exécution, vous pouvez utiliser la commande schedule:list
Artisan:
php artisan schedule:list
Planification des commandes Artisan
En plus de la planification des fermetures, vous pouvez également planifier les commandes Artisan et les commandes système. Par exemple, vous pouvez utiliser la méthode command
pour planifier une commande Artisan en utilisant le nom ou la classe de la commande.
Lorsque vous planifiez des commandes Artisan en utilisant le nom de la classe de la commande, vous pouvez passer un tableau d’arguments de ligne de commande supplémentaires qui doivent être fournis à la commande lorsqu’elle est invoquée:
use App\Console\Commands\SendEmailsCommand;$schedule->command('emails:send Taylor --force')->daily();$schedule->command(SendEmailsCommand::class, )->daily();
Planification de travaux en file d’attente
La méthode job
peut être utilisée pour planifier un travail en file d’attente. Cette méthode fournit un moyen pratique de planifier des travaux en file d’attente sans utiliser la méthode call
pour définir des fermetures pour mettre le travail en file d’attente :
use App\Jobs\Heartbeat;$schedule->job(new Heartbeat)->everyFiveMinutes();
Des deuxième et troisième arguments facultatifs peuvent être fournis à la méthode job
qui spécifie le nom de la file d’attente et la connexion à la file d’attente qui doivent être utilisés pour mettre le travail en file d’attente :
use App\Jobs\Heartbeat;// Dispatch the job to the "heartbeats" queue on the "sqs" connection...$schedule->job(new Heartbeat, 'heartbeats', 'sqs')->everyFiveMinutes();
Commandes Shell de planification
La méthode exec
peut être utilisée pour émettre une commande au système d’exploitation :
$schedule->exec('node /home/forge/script.js')->daily();
Options de fréquence de planification
Nous avons déjà vu quelques exemples de la façon dont vous pouvez configurer une tâche pour qu’elle s’exécute à des intervalles spécifiés. Cependant, il existe de nombreuses autres fréquences de planification de tâches que vous pouvez affecter à une tâche :
Méthode | Description |
---|---|
->cron('* * * * *'); |
Exécuter la tâche sur une planification cron personnalisée |
->everyMinute(); |
Exécuter la tâche toutes les minutes |
->everyTwoMinutes(); |
Exécuter la tâche toutes les deux minutes |
->everyThreeMinutes(); |
Exécuter la tâche toutes les trois minutes |
->everyFourMinutes(); |
Exécuter la tâche toutes les quatre minutes |
->everyFiveMinutes(); |
Exécuter la tâche toutes les cinq minutes |
->everyTenMinutes(); |
Exécuter la tâche toutes les dix minutes |
->everyFifteenMinutes(); |
Exécuter la tâche toutes les quinze minutes |
->everyThirtyMinutes(); |
Exécuter la tâche toutes les trente minutes |
->hourly(); |
Exécuter la tâche toutes les heures |
->hourlyAt(17); |
Exécuter la tâche toutes les heures à 17 minutes de l’heure |
->everyTwoHours(); |
Exécuter la tâche toutes les deux heures |
->everyThreeHours(); |
Exécuter la tâche toutes les trois heures |
->everyFourHours(); |
Exécuter la tâche toutes les quatre heures |
->everySixHours(); |
Exécuter la tâche toutes les six heures |
->daily(); |
Exécuter la tâche tous les jours à minuit |
->dailyAt('13:00'); |
Exécuter la tâche tous les jours à 13 :00 |
->twiceDaily(1, 13); |
Exécuter la tâche chaque jour à 1:00 & 13:00 |
->weekly(); |
Exécuter la tâche chaque dimanche à 00 :00 |
->weeklyOn(1, '8:00'); |
Exécuter la tâche chaque semaine le lundi à 8:00 |
->monthly(); |
Exécuter la tâche le premier jour de chaque mois à 00 :00 |
->monthlyOn(4, '15:00'); |
Exécuter la tâche tous les mois le 4 à 15:00 |
->twiceMonthly(1, 16, '13:00'); |
Exécuter la tâche tous les mois le 1er et le 16 à 13 :00 |
->lastDayOfMonth('15:00'); |
Lancer la tâche le dernier jour du mois à 15 :00 |
->quarterly(); |
Lancer la tâche le premier jour de chaque trimestre à 00 :00 |
->yearly(); |
Exécuter la tâche le premier jour de chaque année à 00:00 |
->yearlyOn(6, 1, '17:00'); |
Exécuter la tâche chaque année le 1er juin à 17 :00 |
->timezone('America/New_York'); |
Définir le fuseau horaire pour la tâche |
Ces méthodes peuvent être combinées avec des contraintes supplémentaires pour créer des planifications encore plus fines qui ne s’exécutent que certains jours de la semaine. Par exemple, vous pouvez programmer une commande pour qu’elle s’exécute chaque semaine le lundi :
// Run once per week on Monday at 1 PM...$schedule->call(function () { //})->weekly()->mondays()->at('13:00');// Run hourly from 8 AM to 5 PM on weekdays...$schedule->command('foo') ->weekdays() ->hourly() ->timezone('America/Chicago') ->between('8:00', '17:00');
Une liste de contraintes de programmation supplémentaires peut être trouvée ci-dessous :
Méthode | Description |
---|---|
->weekdays(); |
Limiter la tâche aux jours de la semaine |
->weekends(); |
Limiter la tâche aux week-ends |
->sundays(); |
Limiter la tâche au dimanche |
->mondays(); |
Limiter la tâche au lundi |
->tuesdays(); |
Limiter la tâche au mardi |
->wednesdays(); |
Limiter la tâche au mercredi |
->thursdays(); |
Limite la tâche au jeudi |
->fridays(); |
Limite la tâche au vendredi |
->saturdays(); |
Limiter la tâche au samedi |
->days(array|mixed); |
Limiter la tâche à des jours spécifiques |
->between($startTime, $endTime); |
Limiter la tâche à s’exécuter entre les heures de début et de fin |
->unlessBetween($startTime, $endTime); |
Limiter la tâche à ne pas s’exécuter entre les heures de début et de fin |
->when(Closure); |
Limiter la tâche en fonction d’un test de vérité |
->environments($env); |
Limiter la tâche à des environnements spécifiques environnements |
Contraintes de jour
La méthode days
peut être utilisée pour limiter l’exécution d’une tâche à des jours spécifiques de la semaine. Par exemple, vous pouvez programmer une commande pour qu’elle s’exécute toutes les heures les dimanches et les mercredis :
$schedule->command('emails:send') ->hourly() ->days();
Alternativement, vous pouvez utiliser les constantes disponibles sur la classe Illuminate\Console\Scheduling\Schedule
lors de la définition des jours auxquels une tâche doit s’exécuter :
use Illuminate\Console\Scheduling\Schedule;$schedule->command('emails:send') ->hourly() ->days();
Contraintes d’intervalle de temps
La méthode between
peut être utilisée pour limiter l’exécution d’une tâche en fonction de l’heure de la journée :
$schedule->command('emails:send') ->hourly() ->between('7:00', '22:00');
De même, la méthode unlessBetween
peut être utilisée pour exclure l’exécution d’une tâche pendant une période de temps :
$schedule->command('emails:send') ->hourly() ->unlessBetween('23:00', '4:00');
Contraintes de test de vérité
La méthode when
peut être utilisée pour limiter l’exécution d’une tâche en fonction du résultat d’un test de vérité donné. En d’autres termes, si la fermeture donnée renvoie true
, la tâche s’exécutera tant qu’aucune autre condition contraignante ne l’empêche de s’exécuter :
$schedule->command('emails:send')->daily()->when(function () { return true;});
La méthode skip
peut être considérée comme l’inverse de when
. Si la méthode skip
renvoie true
, la tâche planifiée ne sera pas exécutée:
$schedule->command('emails:send')->daily()->skip(function () { return true;});
Lorsque l’on utilise des méthodes when
enchaînées, la commande planifiée ne s’exécutera que si toutes les conditions when
renvoient true
.
Contraintes d’environnement
La méthode environments
peut être utilisée pour exécuter des tâches uniquement sur les environnements donnés (tels que définis par la variable d’environnement APP_ENV
) :
$schedule->command('emails:send') ->daily() ->environments();
Timezones
À l’aide de la méthode timezone
, vous pouvez spécifier que l’heure d’une tâche planifiée doit être interprétée dans un fuseau horaire donné :
$schedule->command('report:generate') ->timezone('America/New_York') ->at('2:00')
Si vous attribuez de manière répétée le même fuseau horaire à toutes vos tâches planifiées, vous pouvez définir une méthode scheduleTimezone
dans votre classe App\Console\Kernel
. Cette méthode devrait retourner le fuseau horaire par défaut qui devrait être attribué à toutes les tâches planifiées:
/** * Get the timezone that should be used by default for scheduled events. * * @return \DateTimeZone|string|null */protected function scheduleTimezone(){ return 'America/Chicago';}
{note}. N’oubliez pas que certains fuseaux horaires utilisent l’heure d’été. Lorsque les changements d’heure d’été se produisent, votre tâche planifiée peut s’exécuter deux fois ou même ne pas s’exécuter du tout. Pour cette raison, nous recommandons d’éviter la planification des fuseaux horaires lorsque cela est possible.
Prévenir les chevauchements de tâches
Par défaut, les tâches planifiées seront exécutées même si l’instance précédente de la tâche est toujours en cours d’exécution. Pour empêcher cela, vous pouvez utiliser la méthode withoutOverlapping
:
$schedule->command('emails:send')->withoutOverlapping();
Dans cet exemple, la commande emails:send
Artisan sera exécutée toutes les minutes si elle n’est pas déjà en cours d’exécution. La méthode withoutOverlapping
est particulièrement utile si vous avez des tâches qui varient drastiquement dans leur temps d’exécution, vous empêchant de prédire exactement combien de temps une tâche donnée prendra.
Si nécessaire, vous pouvez spécifier combien de minutes doivent s’écouler avant que le verrou « sans chevauchement » expire. Par défaut, le verrou expire après 24 heures :
$schedule->command('emails:send')->withoutOverlapping(10);
Exécution de tâches sur un seul serveur
{note}. Pour utiliser cette fonctionnalité, votre application doit utiliser le pilote de cache
database
,memcached
,dynamodb
ouredis
comme pilote de cache par défaut de votre application. En outre, tous les serveurs doivent communiquer avec le même serveur de cache central.
Si le planificateur de votre application s’exécute sur plusieurs serveurs, vous pouvez limiter un travail planifié pour qu’il ne s’exécute que sur un seul serveur. Par exemple, supposons que vous ayez une tâche planifiée qui génère un nouveau rapport chaque vendredi soir. Si le planificateur de tâches est exécuté sur trois serveurs de travailleurs, la tâche planifiée s’exécutera sur les trois serveurs et générera le rapport trois fois. Pas bon!
Pour indiquer que la tâche doit s’exécuter sur un seul serveur, utilisez la méthode onOneServer
lors de la définition de la tâche planifiée. Le premier serveur à obtenir la tâche sécurisera un verrou atomique sur la tâche pour empêcher les autres serveurs d’exécuter la même tâche en même temps :
$schedule->command('report:generate') ->fridays() ->at('17:00') ->onOneServer();
Tâches d’arrière-plan
Par défaut, plusieurs tâches planifiées en même temps s’exécuteront séquentiellement en fonction de l’ordre dans lequel elles sont définies dans votre méthode schedule
. Si vous avez des tâches à longue durée d’exécution, cela peut entraîner le démarrage des tâches suivantes beaucoup plus tard que prévu. Si vous souhaitez exécuter des tâches en arrière-plan afin qu’elles puissent toutes s’exécuter simultanément, vous pouvez utiliser la méthode runInBackground
:
$schedule->command('analytics:report') ->daily() ->runInBackground();
{note}. La méthode
runInBackground
ne peut être utilisée que lors de la planification de tâches via les méthodescommand
etexec
.
Mode maintenance
Les tâches planifiées de votre application ne s’exécuteront pas lorsque l’application est en mode maintenance, car nous ne voulons pas que vos tâches interfèrent avec toute maintenance non terminée que vous pourriez effectuer sur votre serveur. Cependant, si vous souhaitez forcer l’exécution d’une tâche même en mode maintenance, vous pouvez appeler la méthode evenInMaintenanceMode
lors de la définition de la tâche :
$schedule->command('emails:send')->evenInMaintenanceMode();
Exécution du planificateur
Maintenant que nous avons appris à définir les tâches planifiées, discutons de la manière de les exécuter réellement sur notre serveur. La commande schedule:run
Artisan évaluera toutes vos tâches planifiées et déterminera si elles doivent être exécutées en fonction de l’heure actuelle du serveur.
Donc, lorsque nous utilisons le planificateur de Laravel, nous n’avons qu’à ajouter une seule entrée de configuration cron à notre serveur qui exécute la commande schedule:run
toutes les minutes. Si vous ne savez pas comment ajouter des entrées cron à votre serveur, envisagez d’utiliser un service tel que Laravel Forge qui peut gérer les entrées cron pour vous :
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Exécuter l’ordonnanceur localement
Typiquement, vous n’ajouteriez pas une entrée cron de l’ordonnanceur à votre machine de développement locale. Au lieu de cela, vous pouvez utiliser la commande schedule:work
Artisan. Cette commande s’exécutera en avant-plan et invoquera le planificateur toutes les minutes jusqu’à ce que vous terminiez la commande:
php artisan schedule:work
Sortie de la tâche
Le planificateur Laravel fournit plusieurs méthodes pratiques pour travailler avec la sortie générée par les tâches planifiées. Tout d’abord, en utilisant la méthode sendOutputTo
, vous pouvez envoyer la sortie dans un fichier pour une inspection ultérieure:
$schedule->command('emails:send') ->daily() ->sendOutputTo($filePath);
Si vous souhaitez ajouter la sortie à un fichier donné, vous pouvez utiliser la méthode appendOutputTo
:
$schedule->command('emails:send') ->daily() ->appendOutputTo($filePath);
En utilisant la méthode emailOutputTo
, vous pouvez envoyer la sortie par courriel à une adresse électronique de votre choix. Avant d’envoyer par courriel la sortie d’une tâche, vous devez configurer les services de courriel de Laravel:
$schedule->command('report:generate') ->daily() ->sendOutputTo($filePath) ->emailOutputTo('');
Si vous voulez seulement envoyer par courriel la sortie si la commande Artisan ou système planifiée se termine avec un code de sortie non nul, utilisez la méthode emailOutputOnFailure
:
$schedule->command('report:generate') ->daily() ->emailOutputOnFailure('');
{note}. Les méthodes
emailOutputTo
,emailOutputOnFailure
,sendOutputTo
etappendOutputTo
sont exclusives aux méthodescommand
etexec
.
Crochets de tâche
À l’aide des méthodes before
et after
, vous pouvez spécifier le code à exécuter avant et après l’exécution de la tâche planifiée :
$schedule->command('emails:send') ->daily() ->before(function () { // The task is about to execute... }) ->after(function () { // The task has executed... });
Les méthodes onSuccess
et onFailure
vous permettent de spécifier le code à exécuter si la tâche planifiée réussit ou échoue. Un échec indique que la commande programmée d’Artisan ou du système s’est terminée avec un code de sortie non nul :
$schedule->command('emails:send') ->daily() ->onSuccess(function () { // The task succeeded... }) ->onFailure(function () { // The task failed... });
Si la sortie est disponible à partir de votre commande, vous pouvez y accéder dans vos hooks after
, onSuccess
ou onFailure
en indiquant le type d’une instance Illuminate\Support\Stringable
comme argument $output
de la définition de fermeture de votre hook :
use Illuminate\Support\Stringable;$schedule->command('emails:send') ->daily() ->onSuccess(function (Stringable $output) { // The task succeeded... }) ->onFailure(function (Stringable $output) { // The task failed... });
Pinging d’URL
À l’aide des méthodes pingBefore
et thenPing
, l’ordonnanceur peut pinguer automatiquement une URL donnée avant ou après l’exécution d’une tâche. Cette méthode est utile pour notifier à un service externe, tel que Envoyer, que votre tâche planifiée commence ou a terminé son exécution :
$schedule->command('emails:send') ->daily() ->pingBefore($url) ->thenPing($url);
Les méthodes pingBeforeIf
et thenPingIf
peuvent être utilisées pour envoyer un ping à une URL donnée uniquement si une condition donnée est true
:
$schedule->command('emails:send') ->daily() ->pingBeforeIf($condition, $url) ->thenPingIf($condition, $url);
Les méthodes pingOnSuccess
et pingOnFailure
peuvent être utilisées pour envoyer un ping à une URL donnée uniquement si la tâche réussit ou échoue. Un échec indique que la commande Artisan ou système programmée s’est terminée avec un code de sortie non nul :
$schedule->command('emails:send') ->daily() ->pingOnSuccess($successUrl) ->pingOnFailure($failureUrl);
Toutes les méthodes ping nécessitent la bibliothèque HTTP Guzzle. Guzzle est généralement installé par défaut dans tous les nouveaux projets Laravel, mais, vous pouvez installer manuellement Guzzle dans votre projet à l’aide du gestionnaire de paquets Composer s’il a été supprimé accidentellement :
composer require guzzlehttp/guzzle
.
Laisser un commentaire