- Inleiding
- Roosters definiëren
- Artisan-opdrachten
- Roosteren van taken in wachtrij
- Roosteren van Shell-opdrachten
- Frequentieopties
- Timezones
- Voorkomen dat taken elkaar overlappen
- Taken op één server uitvoeren
- Taken op de achtergrond
- Onderhoudsmodus
- De scheduler uitvoeren
- De scheduler lokaal uitvoeren
- Taakuitvoer
- Taakhaken
- Inleiding
- Defining Schedules
- Artisan commando’s plannen
- Taken in wachtrij inplannen
- Scheduling Shell Commands
- Schedule Frequency Options
- Dagbeperkingen
- Between Time Constraints
- Truth Test Constraints
- Omgevingsbeperkingen
- Timezones
- Voorkomen dat taken elkaar overlappen
- Taken op één server uitvoeren
- Taken op de achtergrond
- Onderhoudsmodus
- Running The Scheduler
- Running The Scheduler Locally
- Taakuitvoer
- Task Hooks
- Ping URLs
Inleiding
In het verleden, hebt u misschien een cron configuratie geschreven voor elke taak die u op uw server wilde plannen. Dit kan echter al snel een probleem worden omdat uw taak schema niet langer in source control is en u moet SSH in uw server om uw bestaande cron entries te bekijken of extra entries toe te voegen.
Laravel’s command scheduler biedt een nieuwe aanpak voor het beheren van geplande taken op uw server. De scheduler stelt u in staat om vloeiend en expressief uw commando schema te definiëren binnen uw Laravel applicatie zelf. Wanneer je de scheduler gebruikt is er slechts één cron entry nodig op je server. Je opdracht schema wordt gedefinieerd in de app/Console/Kernel.php
file’s schedule
method. Om je op weg te helpen, is een eenvoudig voorbeeld gedefinieerd in de methode.
Defining Schedules
Je kunt al je geplande taken definiëren in de schedule
methode van de App\Console\Kernel
klasse van je applicatie. Om te beginnen, laten we eens kijken naar een voorbeeld. In dit voorbeeld plannen we een afsluiting die elke dag om middernacht wordt aangeroepen. Binnen de closure voeren we een database query uit om een tabel leeg te maken:
<?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(); }}
Naast het gebruik van closures, kunt u ook invokable objecten gebruiken. Invokable objects zijn eenvoudige PHP-klassen die een __invoke
-methode bevatten:
$schedule->call(new DeleteRecentUsers)->daily();
Als u een overzicht wilt zien van uw geplande taken en de volgende keer dat ze moeten worden uitgevoerd, kunt u het schedule:list
Artisan commando gebruiken:
php artisan schedule:list
Artisan commando’s plannen
Naast het plannen van closures, kunt u ook Artisan commando’s en systeemcommando’s plannen. U kunt bijvoorbeeld de methode command
gebruiken om een Artisan commando in te plannen met de naam van het commando of met de class.
Wanneer u Artisan commando’s inplant met de class naam van het commando, kunt u een array van extra command-line argumenten doorgeven die aan het commando moeten worden meegegeven wanneer het wordt aangeroepen:
use App\Console\Commands\SendEmailsCommand;$schedule->command('emails:send Taylor --force')->daily();$schedule->command(SendEmailsCommand::class, )->daily();
Taken in wachtrij inplannen
De methode job
kan worden gebruikt om een taak in een wachtrij in te plannen. Deze methode biedt een handige manier om in de wachtrij geplaatste jobs te plannen zonder de methode call
te gebruiken om sluitingen te definiëren om de job in de wachtrij te plaatsen:
use App\Jobs\Heartbeat;$schedule->job(new Heartbeat)->everyFiveMinutes();
Optionele tweede en derde argumenten kunnen aan de methode job
worden meegegeven die de wachtrijnaam en de wachtrijverbinding specificeren die moeten worden gebruikt om de job in de wachtrij te plaatsen:
use App\Jobs\Heartbeat;// Dispatch the job to the "heartbeats" queue on the "sqs" connection...$schedule->job(new Heartbeat, 'heartbeats', 'sqs')->everyFiveMinutes();
Scheduling Shell Commands
De methode exec
kan worden gebruikt om een commando aan het besturingssysteem te geven:
$schedule->exec('node /home/forge/script.js')->daily();
Schedule Frequency Options
We hebben al een paar voorbeelden gezien van hoe u een taak kunt configureren om op gespecificeerde intervallen uit te voeren. Er zijn echter veel meer taak schema frequenties die u kunt toewijzen aan een taak:
Methode | Beschrijving |
---|---|
->cron('* * * * *'); |
De taak uitvoeren volgens een aangepast cron-schema |
->everyMinute(); |
De taak elke minuut laten uitvoeren |
->everyTwoMinutes(); |
De taak elke twee minuten laten uitvoeren |
->everyThreeMinutes(); |
De taak om de drie minuten uitvoeren |
->everyFourMinutes(); |
De taak om de vier minuten uitvoeren |
->everyFiveMinutes(); |
De taak uitvoeren om de vijf minuten |
->everyTenMinutes(); |
Run de taak om de tien minuten |
->everyFifteenMinutes(); |
Run de taak om de vijftien minuten |
->everyThirtyMinutes(); |
De taak om de dertig minuten uitvoeren |
->hourly(); |
De taak om het uur uitvoeren |
->hourlyAt(17); |
De taak elk uur om 17 minuten na het uur uitvoeren |
->everyTwoHours(); |
De taak elke twee uur uitvoeren |
->everyThreeHours(); |
De taak om de drie uur uitvoeren |
->everyFourHours(); |
De taak om de vier uur uitvoeren |
->everySixHours(); |
De taak uitvoeren om de zes uur |
->daily(); |
De taak elke dag om middernacht uitvoeren |
->dailyAt('13:00'); |
De taak elke dag om 13:00 |
->twiceDaily(1, 13); |
De taak dagelijks om 1:00 uitvoeren& 13:00 |
->weekly(); |
De taak elke zondag om 00:00 uitvoeren:00 |
->weeklyOn(1, '8:00'); |
De taak elke week op maandag om 8:00 uitvoeren |
->monthly(); |
De taak elke eerste dag van de maand om 00 uur uitvoeren:00 |
->monthlyOn(4, '15:00'); |
De taak elke maand uitvoeren op de 4e om 15:00 |
->twiceMonthly(1, 16, '13:00'); |
De taak elke maand uitvoeren op de 1e en de 16e om 13:00 |
->twiceMonthly(1, 16, '13:00'); |
De taak elke maand uitvoeren op de 1e en de 16e om 13:00:00 |
->lastDayOfMonth('15:00'); |
De taak uitvoeren op de laatste dag van de maand om 15 uur:00 |
->quarterly(); |
De taak op de eerste dag van elk kwartaal om 00 uur laten uitvoeren:00 |
->yearly(); |
De taak uitvoeren op de eerste dag van elk jaar om 00:00 |
->yearlyOn(6, 1, '17:00'); |
De taak elk jaar uitvoeren op 1 juni om 17:00 |
->yearlyOn(6, 1, '17:00'); |
De taak elk jaar uitvoeren op 1 juni om 17:00:00 |
->timezone('America/New_York'); |
De tijdzone voor de taak instellen |
Deze methoden kunnen worden gecombineerd met extra beperkingen om nog fijnmaziger schema’s te maken die alleen op bepaalde dagen van de week worden uitgevoerd. U kunt bijvoorbeeld een commando plannen dat wekelijks op maandag wordt uitgevoerd:
// 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');
Een lijst met aanvullende beperkingen voor schema’s vindt u hieronder:
Methode | Omschrijving |
---|---|
->weekdays(); |
Limiteer de taak tot weekdagen |
->weekends(); |
Beperk de taak tot weekends |
->sundays(); |
Beperk de taak tot zondag |
->mondays(); |
Beperk de taak tot maandag |
->tuesdays(); |
Beperk de taak tot dinsdag |
->wednesdays(); |
Beperk de taak tot woensdag |
->wednesdays(); |
Beperk de taak tot woensdag |
->thursdays(); |
Limiteer de taak tot donderdag |
->fridays(); |
Limiteer de taak tot vrijdag |
->saturdays(); |
Beperk de taak tot zaterdag |
->days(array|mixed); |
Beperk de taak tot specifieke dagen |
->between($startTime, $endTime); |
Limiteer de taak om te worden uitgevoerd tussen begin- en eindtijd |
->unlessBetween($startTime, $endTime); |
Limiteer de taak om niet te worden uitgevoerd tussen begin- en eindtijd |
->unlessBetween($startTime, $endTime); |
Limiteer de taak om niet te worden uitgevoerd tussen begin- en eindtijd |
->when(Closure); |
Limiteer de taak op basis van een waarheidstest |
->environments($env); |
Limiteer de taak tot specifieke omgevingen |
Dagbeperkingen
De methode days
kan worden gebruikt om de uitvoering van een taak te beperken tot specifieke dagen van de week. U kunt bijvoorbeeld een opdracht plannen om elk uur op zondag en woensdag te worden uitgevoerd:
$schedule->command('emails:send') ->hourly() ->days();
Als alternatief kunt u de constanten gebruiken die beschikbaar zijn voor de klasse Illuminate\Console\Scheduling\Schedule
bij het definiëren van de dagen waarop een taak moet worden uitgevoerd:
use Illuminate\Console\Scheduling\Schedule;$schedule->command('emails:send') ->hourly() ->days();
Between Time Constraints
De methode between
kan worden gebruikt om de uitvoering van een taak te beperken op basis van het tijdstip van de dag:
$schedule->command('emails:send') ->hourly() ->between('7:00', '22:00');
Ook kan de methode unlessBetween
worden gebruikt om de uitvoering van een taak gedurende een bepaalde periode uit te sluiten:
$schedule->command('emails:send') ->hourly() ->unlessBetween('23:00', '4:00');
Truth Test Constraints
De methode when
kan worden gebruikt om de uitvoering van een taak te beperken op basis van het resultaat van een gegeven waarheidstest. Met andere woorden, als de gegeven afsluiting true
teruggeeft, zal de taak worden uitgevoerd zolang geen andere beperkende voorwaarden de taak verhinderen uit te voeren:
$schedule->command('emails:send')->daily()->when(function () { return true;});
De methode skip
kan worden gezien als het inverse van when
. Als de skip
-methode true
retourneert, wordt de geplande opdracht niet uitgevoerd:
$schedule->command('emails:send')->daily()->skip(function () { return true;});
Wanneer u geketende when
-methoden gebruikt, wordt de geplande opdracht alleen uitgevoerd als alle when
-voorwaarden true
retourneren.
Omgevingsbeperkingen
De methode environments
kan worden gebruikt om taken alleen op de gegeven omgevingen uit te voeren (zoals gedefinieerd door de omgevingsvariabele APP_ENV
):
$schedule->command('emails:send') ->daily() ->environments();
Timezones
Met de methode timezone
kunt u opgeven dat de tijd van een geplande taak binnen een bepaalde tijdzone moet worden geïnterpreteerd:
$schedule->command('report:generate') ->timezone('America/New_York') ->at('2:00')
Als u herhaaldelijk dezelfde tijdzone aan al uw geplande taken toewijst, wilt u misschien een methode scheduleTimezone
in uw App\Console\Kernel
klasse definiëren. Deze methode moet de standaardtijdzone teruggeven die aan alle geplande taken moet worden toegewezen:
/** * Get the timezone that should be used by default for scheduled events. * * @return \DateTimeZone|string|null */protected function scheduleTimezone(){ return 'America/Chicago';}
{note} Vergeet niet dat sommige tijdzones gebruik maken van zomertijd. Wanneer de zomertijd verandert, kan het zijn dat uw geplande taak twee keer of zelfs helemaal niet wordt uitgevoerd. Daarom raden we u aan tijdzoneplanningen waar mogelijk te vermijden.
Voorkomen dat taken elkaar overlappen
Zelfs als de vorige instantie van de taak nog actief is, worden geplande taken standaard uitgevoerd. Om dit te voorkomen, kunt u de methode withoutOverlapping
gebruiken:
$schedule->command('emails:send')->withoutOverlapping();
In dit voorbeeld wordt de emails:send
Artisan-opdracht elke minuut uitgevoerd als deze nog niet is uitgevoerd. De methode withoutOverlapping
is vooral nuttig als u taken hebt die drastisch variëren in hun uitvoeringstijd, waardoor u niet precies kunt voorspellen hoe lang een bepaalde taak zal duren.
Als dat nodig is, kunt u opgeven hoeveel minuten moeten verstrijken voordat het “zonder overlapping” slot verloopt. Standaard verloopt het slot na 24 uur:
$schedule->command('emails:send')->withoutOverlapping(10);
Taken op één server uitvoeren
{note} Om deze functie te kunnen gebruiken, moet uw toepassing het
database
-,memcached
-,dynamodb
– ofredis
-cachestuurprogramma gebruiken als het standaard-cachestuurprogramma van uw toepassing. Bovendien moeten alle servers communiceren met dezelfde centrale cachingserver.
Als de planner van uw toepassing op meerdere servers wordt uitgevoerd, kunt u een geplande taak beperken tot slechts één server. Stel dat u bijvoorbeeld een geplande taak hebt die elke vrijdagavond een nieuw rapport genereert. Als de taakplanner op drie werkservers draait, zal de geplande taak op alle drie de servers draaien en het rapport drie keer genereren. Niet goed!
Om aan te geven dat de taak op slechts één server moet draaien, gebruik je de onOneServer
methode bij het definiëren van de geplande taak. De eerste server die de taak krijgt, krijgt een atomair slot op de taak om te voorkomen dat andere servers dezelfde taak op hetzelfde moment uitvoeren:
$schedule->command('report:generate') ->fridays() ->at('17:00') ->onOneServer();
Taken op de achtergrond
Zorg er standaard voor dat meerdere taken die op hetzelfde moment zijn gepland, opeenvolgend worden uitgevoerd op basis van de volgorde waarin ze zijn gedefinieerd in uw schedule
-methode. Als u langlopende taken hebt, kan dit ertoe leiden dat opeenvolgende taken veel later beginnen dan verwacht. Als u taken op de achtergrond wilt laten lopen, zodat ze allemaal tegelijk kunnen worden uitgevoerd, kunt u de methode runInBackground
gebruiken:
$schedule->command('analytics:report') ->daily() ->runInBackground();
{note} De methode
runInBackground
mag alleen worden gebruikt wanneer taken worden gepland via de methodencommand
enexec
.
Onderhoudsmodus
De geplande taken van uw toepassing worden niet uitgevoerd wanneer de toepassing zich in de onderhoudsmodus bevindt, omdat we niet willen dat uw taken het onvoltooide onderhoud dat u mogelijk op uw server uitvoert, verstoren. Als u echter een taak wilt forceren om zelfs in onderhoudsmodus te draaien, kunt u de evenInMaintenanceMode
methode aanroepen wanneer u de taak definieert:
$schedule->command('emails:send')->evenInMaintenanceMode();
Running The Scheduler
Nu we hebben geleerd hoe we geplande taken kunnen definiëren, laten we eens bespreken hoe we ze daadwerkelijk op onze server kunnen uitvoeren. Het schedule:run
Artisan commando zal al uw geplande taken evalueren en bepalen of ze moeten worden uitgevoerd op basis van de huidige tijd van de server.
Dus, wanneer we Laravel’s scheduler gebruiken, hoeven we slechts een enkel cron configuratie-item aan onze server toe te voegen dat het schedule:run
commando elke minuut uitvoert. Als je niet weet hoe je cron entries aan je server moet toevoegen, overweeg dan het gebruik van een service zoals Laravel Forge die de cron entries voor je kan beheren:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Running The Scheduler Locally
Typisch gezien zou je geen scheduler cron entry toevoegen aan je lokale ontwikkelmachine. In plaats daarvan kunt u het schedule:work
Artisan commando gebruiken. Dit commando draait op de voorgrond en roept de planner elke minuut op totdat u het commando beëindigt:
php artisan schedule:work
Taakuitvoer
De Laravel planner biedt verschillende handige methoden om te werken met de uitvoer die door geplande taken wordt gegenereerd. Ten eerste, met behulp van de sendOutputTo
methode, kunt u de uitvoer naar een bestand sturen voor latere inspectie:
$schedule->command('emails:send') ->daily() ->sendOutputTo($filePath);
Als u de uitvoer wilt toevoegen aan een bepaald bestand, kunt u gebruik maken van de appendOutputTo
methode:
$schedule->command('emails:send') ->daily() ->appendOutputTo($filePath);
Met behulp van de emailOutputTo
methode, kunt u de uitvoer e-mailen naar een e-mail adres van uw keuze. Voordat je de uitvoer van een taak e-mailt, moet je de e-maildiensten van Laravel configureren:
$schedule->command('report:generate') ->daily() ->sendOutputTo($filePath) ->emailOutputTo('');
Als je de uitvoer alleen wilt e-mailen als de geplande Artisan of systeemopdracht eindigt met een exitcode van nul, gebruik dan de methode emailOutputOnFailure
:
$schedule->command('report:generate') ->daily() ->emailOutputOnFailure('');
{note} De methoden
emailOutputTo
,emailOutputOnFailure
,sendOutputTo
enappendOutputTo
zijn exclusief de methodencommand
enexec
.
Task Hooks
Met de methoden before
en after
kunt u code opgeven die moet worden uitgevoerd voor en na de uitvoering van de geplande taak:
$schedule->command('emails:send') ->daily() ->before(function () { // The task is about to execute... }) ->after(function () { // The task has executed... });
Met de methoden onSuccess
en onFailure
kunt u code opgeven die moet worden uitgevoerd als de geplande taak slaagt of mislukt. Een mislukking geeft aan dat de geplande Artisan of systeem commando eindigde met een niet-nul exit code:
$schedule->command('emails:send') ->daily() ->onSuccess(function () { // The task succeeded... }) ->onFailure(function () { // The task failed... });
Als er uitvoer beschikbaar is van uw commando, kunt u deze benaderen in uw after
, onSuccess
of onFailure
hooks door een Illuminate\Support\Stringable
instantie te typeren als het $output
argument van uw hook’s closure definitie:
use Illuminate\Support\Stringable;$schedule->command('emails:send') ->daily() ->onSuccess(function (Stringable $output) { // The task succeeded... }) ->onFailure(function (Stringable $output) { // The task failed... });
Ping URLs
Met behulp van de pingBefore
en thenPing
methodes, kan de scheduler automatisch een bepaalde URL pingen voor of nadat een taak is uitgevoerd. Deze methode is handig om een externe service, zoals Envoyer, te laten weten dat uw geplande taak begint of klaar is met uitvoeren:
$schedule->command('emails:send') ->daily() ->pingBefore($url) ->thenPing($url);
De methoden pingBeforeIf
en thenPingIf
kunnen worden gebruikt om een bepaalde URL alleen te pingen als een bepaalde voorwaarde true
is:
$schedule->command('emails:send') ->daily() ->pingBeforeIf($condition, $url) ->thenPingIf($condition, $url);
De methoden pingOnSuccess
en pingOnFailure
kunnen worden gebruikt om een bepaalde URL alleen te pingen als de taak slaagt of mislukt. Een mislukking geeft aan dat de geplande Artisan of systeem opdracht eindigde met een niet-nul exit code:
$schedule->command('emails:send') ->daily() ->pingOnSuccess($successUrl) ->pingOnFailure($failureUrl);
Alle ping methoden vereisen de Guzzle HTTP bibliotheek. Guzzle wordt standaard geïnstalleerd in alle nieuwe Laravel projecten, maar je kunt Guzzle handmatig in je project installeren met de Composer package manager als het per ongeluk is verwijderd:
composer require guzzlehttp/guzzle
Geef een antwoord