- 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ó
- Ütemtervek definiálása
- Artisan parancsok ütemezése
- Sorba állított feladatok ütemezése
- Héjparancsok ütemezése
- Az ütemezés gyakorisági beállításai
- Napi korlátozások
- Korlátozások
- Igazságteszt korlátozások
- Környezeti korlátozások
- Időzónák
- A feladatok átfedésének megakadályozása
- Futtatott feladatok egy szerveren
- Háttérfeladatok
- Karbantartási mód
- Az ütemező futtatása
- Az ütemező helyi futtatása
- A feladat kimenete
- Task Hooks
- URL címek pingelése
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:
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:
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
vagyredis
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 acommand
ésexec
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
ésappendOutputTo
módszerek kizárólag acommand
ésexec
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
Vélemény, hozzászólás?