• Bevezetés
  • Ütemezések definiálása
    • Artisan parancsok ütemezése
    • Sorba állított munkák ütemezése
    • Kagyló parancsok ütemezése
    • Ütemezési gyakorisági beállítások
    • Időzónák
    • Az átfedések megelőzése
    • .

    • A feladatok futtatása egy kiszolgálón
    • Háttérfeladatok
    • Karbantartási mód
  • Az ütemező futtatása
    • Az ütemező helyi futtatása
  • A feladatok kimenete
  • A feladatok horgai

Előszó

A múltban, írhatott egy cron konfigurációs bejegyzést minden olyan feladathoz, amelyet be kellett ütemeznie a kiszolgálón. Ez azonban gyorsan fájdalmas lehet, mert a feladatütemezés már nem a forráskontrolban van, és SSH-n keresztül kell belépnie a szerverére, hogy megnézze a meglévő cron-bejegyzéseket, vagy további bejegyzéseket adjon hozzá.

A Laravel parancsütemezője új megközelítést kínál a szerverén lévő ütemezett feladatok kezeléséhez. Az ütemező lehetővé teszi, hogy folyékonyan és kifejezően definiálja a parancs ütemezését magában a Laravel alkalmazásban. Az ütemező használata esetén csak egyetlen cron bejegyzésre van szükség a szerveren. A feladatütemezését a app/Console/Kernel.php fájl schedule metódusában határozza meg. A kezdés megkönnyítése érdekében a metóduson belül egy egyszerű példa van definiálva.

Ütemtervek definiálása

Az összes ütemezett feladatát az alkalmazás App\Console\Kernel osztályának schedule metódusában definiálhatja. A kezdéshez nézzünk meg egy példát. Ebben a példában egy lezárást fogunk ütemezni, amelyet minden nap éjfélkor hívunk meg. A zárlaton belül egy adatbázis-lekérdezést fogunk végrehajtani egy tábla törléséhez:

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

A zárlatok használatával történő ütemezés mellett meghívható objektumokat is ütemezhetünk. A meghívható objektumok olyan egyszerű PHP osztályok, amelyek tartalmaznak egy __invoke metódust:

$schedule->call(new DeleteRecentUsers)->daily();

Ha áttekintést szeretne kapni az ütemezett feladatokról és azok következő ütemezett lefutásáról, akkor használhatja az schedule:list Artisan parancsot:

php artisan schedule:list

Artisan parancsok ütemezése

A lezárások ütemezése mellett Artisan parancsokat és rendszerparancsokat is ütemezhet. Például a command módszerrel ütemezhet egy Artisan-parancsot a parancs neve vagy osztálya alapján.

Az Artisan-parancsok ütemezése esetén a parancs osztályának neve alapján átadhat egy további parancssori argumentumokból álló tömböt, amelyet a parancs meghívásakor meg kell adni:

use App\Console\Commands\SendEmailsCommand;$schedule->command('emails:send Taylor --force')->daily();$schedule->command(SendEmailsCommand::class, )->daily();

Sorba állított feladatok ütemezése

A job módszer használható sorba állított feladatok ütemezésére. Ez a módszer kényelmes módot biztosít a sorba állított munkák ütemezésére anélkül, hogy a call metódust használnánk a munkák sorba állításához szükséges lezárások meghatározására:

use App\Jobs\Heartbeat;$schedule->job(new Heartbeat)->everyFiveMinutes();

A job metódusnak választható második és harmadik argumentumot lehet megadni, amely megadja a sorba állításhoz használandó sorba állítás nevét és a sorba állítási kapcsolatot:

use App\Jobs\Heartbeat;// Dispatch the job to the "heartbeats" queue on the "sqs" connection...$schedule->job(new Heartbeat, 'heartbeats', 'sqs')->everyFiveMinutes();

Héjparancsok ütemezése

A exec metódus segítségével parancsot adhatunk ki az operációs rendszernek:

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

Az ütemezés gyakorisági beállításai

Már láttunk néhány példát arra, hogyan állíthatjuk be, hogy egy feladat meghatározott időközönként fusson. Azonban sokkal több olyan feladat ütemezési gyakoriság létezik, amelyet hozzárendelhet egy feladathoz:

.

.

A feladat időzónájának beállítása

Módszer Megnevezés
->cron('* * * * *'); A feladat futtatása egyéni cron ütemezéssel
->everyMinute(); Futtassa a feladatot percenként
->everyTwoMinutes(); Futtassa a feladatot kétpercenként
->everyThreeMinutes(); Futtassa a feladatot hárompercenként
->everyFourMinutes(); Futtassa a feladatot négypercenként
->everyFiveMinutes(); Futtassa a feladatot. ötpercenként
->everyTenMinutes(); Tízpercenként futtatja a feladatot
->everyFifteenMinutes(); Tizenötpercenként futtatja a feladatot
->everyThirtyMinutes(); Futtassa a feladatot harminc percenként
->hourly(); Futtassa a feladatot óránként
->hourlyAt(17); Futtassa a feladatot minden órában 17 perckor
->everyTwoHours(); Futtassa a feladatot kétóránként
->everyThreeHours(); Futtassa a feladatot háromóránként
->everyFourHours(); Futtassa a feladatot négyóránként
->everySixHours(); Futtassa a feladatot háromóránként
->everySixHours(); Futtassa a feladatot. hatóránként
->daily(); Futtassa a feladatot minden nap éjfélkor
->dailyAt('13:00'); Futtassa a feladatot minden nap 13 órakor:00
->twiceDaily(1, 13); Futtassa a feladatot naponta 1:00-kor & 13:00
->weekly(); Futtassa a feladatot minden vasárnap 00 órakor:00
->weeklyOn(1, '8:00'); Futtassa a feladatot minden héten hétfőn 8:00
->monthly(); Futtassa a feladatot minden hónap első napján 00 órakor:00
->monthlyOn(4, '15:00'); Futtassa a feladatot minden hónap 4-én 15:00-kor
->twiceMonthly(1, 16, '13:00'); Futtassa a feladatot havonta 1-jén és 16-án 13 órakor:00
->lastDayOfMonth('15:00'); Futtassa a feladatot a hónap utolsó napján 15 órakor:00
->quarterly(); Futtassa a feladatot minden negyedév első napján 00 órakor:00
->yearly(); Futtassa a feladatot minden év első napján 00:00
->yearlyOn(6, 1, '17:00'); Futtassa a feladatot minden év június 1-jén 17 órakor:00
->timezone('America/New_York');

Ezek a módszerek további korlátozásokkal kombinálva még finomabb ütemezéseket hozhatnak létre, amelyek csak a hét bizonyos napjain futnak. Például ütemezhet egy parancsot úgy, hogy az hetente hétfőn fusson:

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

A további ütemezési korlátozások listáját alább találja:

.

korlátozza.

.

Módszer Megnevezés
->weekdays(); A feladat hétköznapokra korlátozása
->weekends(); A feladatot hétvégére korlátozza
->sundays(); A feladatot vasárnapra korlátozza
->mondays(); A feladatot hétfőre korlátozza
->tuesdays(); A feladatot keddre korlátozza
->wednesdays(); A feladatot keddre korlátozza. szerdára
->thursdays(); A feladatot csütörtökre
->fridays(); A feladatot péntekre
->saturdays(); A feladat szombatra korlátozása
->days(array|mixed); A feladat meghatározott napokra korlátozása
->between($startTime, $endTime); A feladat futásának korlátozása a kezdési és a befejezési időpontok között
->unlessBetween($startTime, $endTime); A feladat futásának korlátozása a kezdési és a befejezési időpontok között. végidőpontok között
->when(Closure); A feladat korlátozása egy igazságteszt alapján
->environments($env); A feladat korlátozása meghatározott környezetekre

Napi korlátozások

A days módszerrel a feladat végrehajtása a hét meghatározott napjaira korlátozható. Például ütemezhetünk egy parancsot úgy, hogy vasárnap és szerdán óránként fusson:

$schedule->command('emails:send') ->hourly() ->days();

Alternatívaként használhatjuk a Illuminate\Console\Scheduling\Schedule osztályon elérhető konstansokat, amikor meghatározzuk, hogy mely napokon fusson egy feladat:

use Illuminate\Console\Scheduling\Schedule;$schedule->command('emails:send') ->hourly() ->days();

Korlátozások

A between módszer használható a feladat végrehajtásának napszakok szerinti korlátozására:

Hasonlóképpen, a unlessBetween módszer használható egy feladat végrehajtásának kizárására egy bizonyos időszakra:

$schedule->command('emails:send') ->hourly() ->unlessBetween('23:00', '4:00');

Igazságteszt korlátozások

A when módszer használható egy feladat végrehajtásának korlátozására egy adott igazságteszt eredménye alapján. Más szóval, ha az adott zárlat true-et ad vissza, a feladat addig fog végrehajtódni, amíg más korlátozó feltétel nem akadályozza a feladat végrehajtását:

$schedule->command('emails:send')->daily()->when(function () { return true;});

A skip módszer a when inverzének tekinthető. Ha a skip metódus true-et ad vissza, az ütemezett feladat nem fog végrehajtódni:

$schedule->command('emails:send')->daily()->skip(function () { return true;});

Láncolt when metódusok használata esetén az ütemezett parancs csak akkor fog végrehajtódni, ha az összes when feltétel true-et ad vissza.

Környezeti korlátozások

A environments módszerrel csak az adott (a APP_ENV környezeti változó által meghatározott) környezetekben lehet feladatokat végrehajtani:

$schedule->command('emails:send') ->daily() ->environments();

Időzónák

A timezone módszerrel megadhatjuk, hogy egy ütemezett feladat idejét egy adott időzónán belül kell értelmezni:

$schedule->command('report:generate') ->timezone('America/New_York') ->at('2:00')

Ha ismételten ugyanazt az időzónát rendeljük az összes ütemezett feladatunkhoz, érdemes egy scheduleTimezone módszert definiálni a App\Console\Kernel osztályban. Ennek a metódusnak vissza kell adnia az alapértelmezett időzónát, amelyet minden ütemezett feladathoz hozzá kell rendelni:

/** * Get the timezone that should be used by default for scheduled events. * * @return \DateTimeZone|string|null */protected function scheduleTimezone(){ return 'America/Chicago';}

{note} Ne feledje, hogy egyes időzónák a nyári időszámítást használják. A nyári időszámítás változásakor előfordulhat, hogy az ütemezett feladat kétszer fut le, vagy egyáltalán nem fut le. Ezért javasoljuk, hogy lehetőség szerint kerülje az időzónás ütemezést.

A feladatok átfedésének megakadályozása

Az ütemezett feladatok alapértelmezés szerint akkor is lefutnak, ha a feladat előző példánya még fut. Ennek megakadályozására használhatja a withoutOverlapping módszert:

$schedule->command('emails:send')->withoutOverlapping();

Ebben a példában az emails:send Artisan parancs minden percben lefut, ha még nem fut. A withoutOverlapping módszer különösen akkor hasznos, ha olyan feladatai vannak, amelyek végrehajtási ideje drasztikusan változik, és így nem tudja pontosan megjósolni, hogy egy adott feladat mennyi ideig fog tartani.

Szükség esetén megadhatja, hogy hány percnek kell eltelnie, mielőtt az “átfedés nélkül” zárolás lejár. Alapértelmezés szerint a zárolás 24 óra után jár le:

$schedule->command('emails:send')->withoutOverlapping(10);

Futtatott feladatok egy szerveren

{note} E funkció kihasználásához az alkalmazásnak a database, memcached, dynamodb vagy redis gyorsítótár-illesztőprogramot kell használnia az alkalmazás alapértelmezett gyorsítótár-illesztőprogramjaként. Ezenkívül minden kiszolgálónak ugyanazzal a központi gyorsítótár-kiszolgálóval kell kommunikálnia.

Ha az alkalmazás ütemezője több kiszolgálón fut, korlátozhatja az ütemezett feladatot, hogy csak egyetlen kiszolgálón hajtsa végre. Tegyük fel például, hogy van egy ütemezett feladata, amely minden péntek este új jelentést generál. Ha a feladatütemező három munkakiszolgálón fut, akkor az ütemezett feladat mindhárom kiszolgálón fut, és háromszor generálja a jelentést. Nem jó!

Az ütemezett feladat definiálásakor használja a onOneServer módszert annak jelzésére, hogy a feladat csak egy kiszolgálón fusson. A feladatot elsőként megkapó kiszolgáló atomi zárolást biztosít a feladatra, hogy megakadályozza, hogy más kiszolgálók egyidejűleg futtassák ugyanazt a feladatot:

$schedule->command('report:generate') ->fridays() ->at('17:00') ->onOneServer();

Háttérfeladatok

Egyszerre ütemezett több feladat alapértelmezés szerint a schedule módszerben meghatározott sorrend alapján egymás után fog végrehajtódni. Ha hosszú ideig futó feladatai vannak, ez azt eredményezheti, hogy a következő feladatok a vártnál jóval később indulnak el. Ha a feladatokat a háttérben szeretné futtatni, hogy azok mindegyike egyszerre fusson, használhatja a runInBackground módszert:

$schedule->command('analytics:report') ->daily() ->runInBackground();

{note} A runInBackground módszer csak akkor használható, ha a command és exec módszerrel ütemezi a feladatokat.

Karbantartási mód

Az alkalmazás ütemezett feladatai nem futnak, amikor az alkalmazás karbantartási módban van, mivel nem szeretnénk, ha a feladatok megzavarnák a szerveren esetleg elvégzendő befejezetlen karbantartást. Ha azonban szeretnénk kikényszeríteni egy feladat futtatását karbantartási üzemmódban is, akkor a feladat definiálásakor meghívhatjuk a evenInMaintenanceMode metódust:

$schedule->command('emails:send')->evenInMaintenanceMode();

Az ütemező futtatása

Most, hogy megtanultuk, hogyan definiáljuk az ütemezett feladatokat, beszéljünk arról, hogyan is kell azokat ténylegesen futtatni a szerverünkön. Az schedule:run Artisan parancs kiértékeli az összes ütemezett feladatot, és meghatározza, hogy a szerver aktuális ideje alapján kell-e futtatni őket.

A Laravel ütemezőjének használatakor tehát csak egyetlen cron konfigurációs bejegyzést kell hozzáadnunk a szerverünkhöz, amely percenként futtatja a schedule:run parancsot. Ha nem tudja, hogyan adjon hozzá cron-bejegyzéseket a szerveréhez, fontolja meg egy olyan szolgáltatás használatát, mint például a Laravel Forge, amely képes kezelni a cron-bejegyzéseket Ön helyett:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Az ütemező helyi futtatása

Tipikusan nem adna hozzá egy ütemező cron-bejegyzést a helyi fejlesztőgépéhez. Ehelyett használhatja az schedule:work Artisan parancsot. Ez a parancs az előtérben fog futni, és minden percben meghívja az ütemezőt, amíg meg nem szünteti a parancsot:

php artisan schedule:work

A feladat kimenete

A Laravel ütemező több kényelmes módszert is biztosít az ütemezett feladatok által generált kimenettel való munkához. Először is, a sendOutputTo módszerrel elküldheti a kimenetet egy fájlba későbbi megtekintés céljából:

$schedule->command('emails:send') ->daily() ->sendOutputTo($filePath);

Ha a kimenetet egy adott fájlhoz szeretné csatolni, akkor a appendOutputTo módszert használhatja:

$schedule->command('emails:send') ->daily() ->appendOutputTo($filePath);

A emailOutputTo módszerrel elküldheti a kimenetet egy szabadon választott e-mail címre. Mielőtt e-mailben elküldené egy feladat kimenetét, konfigurálnia kell a Laravel e-mail szolgáltatásait:

$schedule->command('report:generate') ->daily() ->sendOutputTo($filePath) ->emailOutputTo('');

Ha csak akkor szeretné e-mailben küldeni a kimenetet, ha az ütemezett Artisan vagy rendszerparancs nem nulla kilépési kóddal fejeződik be, használja a emailOutputOnFailure módszert:

$schedule->command('report:generate') ->daily() ->emailOutputOnFailure('');

{note} A emailOutputTo, emailOutputOnFailure, sendOutputTo és appendOutputTo módszerek kizárólag a command és exec módszerekhez tartoznak.

Task Hooks

A before és after metódusok segítségével megadhatja az ütemezett feladat végrehajtása előtt és után végrehajtandó kódot:

$schedule->command('emails:send') ->daily() ->before(function () { // The task is about to execute... }) ->after(function () { // The task has executed... });

A onSuccess és onFailure metódusok segítségével megadhatja az ütemezett feladat sikere vagy sikertelensége esetén végrehajtandó kódot. A sikertelenség azt jelzi, hogy az ütemezett Artisan- vagy rendszerparancs nem nulla kilépési kóddal fejeződött be:

$schedule->command('emails:send') ->daily() ->onSuccess(function () { // The task succeeded... }) ->onFailure(function () { // The task failed... });

Ha a parancsból származó kimenet elérhető, akkor azt a after, onSuccess vagy onFailure kampókban elérheti egy Illuminate\Support\Stringable példány típusjelzésével, mint a kampó záródefiníciójának $output argumentuma:

use Illuminate\Support\Stringable;$schedule->command('emails:send') ->daily() ->onSuccess(function (Stringable $output) { // The task succeeded... }) ->onFailure(function (Stringable $output) { // The task failed... });

URL címek pingelése

A pingBefore és thenPing metódusok használatával az ütemező automatikusan pingelhet egy adott URL címet egy feladat végrehajtása előtt vagy után. Ez a módszer hasznos egy külső szolgáltatás, például az Envoyer értesítésére, hogy az ütemezett feladat megkezdődött vagy befejeződött:

$schedule->command('emails:send') ->daily() ->pingBefore($url) ->thenPing($url);

A pingBeforeIf és thenPingIf metódusokkal egy adott URL-t csak akkor lehet pingelni, ha egy adott feltétel true:

$schedule->command('emails:send') ->daily() ->pingBeforeIf($condition, $url) ->thenPingIf($condition, $url);

A pingOnSuccess és pingOnFailure metódusokkal egy adott URL-t csak akkor lehet pingelni, ha a feladat sikeres vagy sikertelen. A sikertelenség azt jelzi, hogy az ütemezett Artisan vagy rendszerparancs nem nulla kilépési kóddal fejeződött be:

$schedule->command('emails:send') ->daily() ->pingOnSuccess($successUrl) ->pingOnFailure($failureUrl);

A ping-módszerek mindegyike a Guzzle HTTP könyvtárat igényli. A Guzzle általában alapértelmezés szerint minden új Laravel projektbe telepítve van, de a Composer csomagkezelő segítségével manuálisan is telepítheti a Guzzle-t a projektjébe, ha véletlenül eltávolították:

composer require guzzlehttp/guzzle