Jak v produkci běží fronty (queue:work) a plánovač (schedule:work)
Pochopte, jak Laravel 12 plánuje úlohy přes routes/console.php a jak v produkčním Docker kontejneru zajistit periodické spouštění scheduleru a zpracování front bez cron démona na hostiteli.
Asynchronní zpracování a plánovač v Laravelu 12
Produkční webové aplikace nesmí zdržovat uživatele dlouhotrvajícími operacemi (jako je odesílání e-mailů, generování PDF reportů, náročné audity nebo synchronizace externích API). Laravel nabízí dva integrované pilíře pro běh úloh na pozadí:
- Fronty (Queues): Asynchronní zpracování zpráv na vyžádání (
dispatch). - Plánovač úloh (Task Scheduler): Periodické spouštění úloh podle časového harmonogramu.
Zjednodušení v Laravelu 12: Plánovač v routes/console.php
V předchozích verzích Laravelu se plánované úlohy registrovaly v třídě app/Console/Kernel.php v metodě schedule(). Laravel 12 tento zastaralý kernel odstranil a sjednotil veškerou konzolovou logiku do souboru routes/console.php.
Pomocí fasády Illuminate\Support\Facades\Schedule můžete plánovat Artisan příkazy, anonymní funkce i frontové joby:
// Spuštění našeho Zero-Hallucination auditu každou noc ve 3:00
Schedule::command('curriculum:verify')->dailyAt('03:00');
// Spuštění promazání neaktivních anonymních profilů jednou týdně
Schedule::call(function () {
// ...
})->weekly();
Jak plánovač reálně funguje v operačním systému
Plánovač v Laravelu není samostatný démon, který by sám od sebe trvale běžel na pozadí. V klasickém Linuxovém prostředí se spoléhá na jediný systémový cron záznam na hostiteli, který se spouští každou minutu:
* * * * * cd /cesta-k-projektu && php artisan schedule:run >> /dev/null 2>&1
Při každém zavolání schedule:run Laravel vyhodnotí aktuální čas proti všem naplánovaným úlohám v routes/console.php a spustí pouze ty, jejichž čas právě nastal.
V Dockerizovaných a kontejnerových prostředích (jako je naše architektura s FrankenPHP) však často nechceme instalovat cron démona do kontejneru. Laravel proto nabízí příkaz:
php artisan schedule:work
Tento příkaz udržuje dlouhotrvající proces v paměti a každou minutu sám interně vyvolá schedule:run.
Produkční provoz asynchronních front (queue:work)
Když do fronty odešlete Job (MyJob::dispatch()), Laravel jej uloží do zvoleného backendu (PostgreSQL tabulka jobs, Redis, Amazon SQS atd.).
Ke zpracování zpráv slouží konzolový worker:
php artisan queue:work --tries=3 --timeout=90
Zásadní pravidlo pro produkční nasazení workerů:
Příkaz queue:work načte celou aplikaci (včetně všech PHP tříd a konfigurace) do paměti RAM a drží ji tam pro dosažení maximální rychlosti. Při nasazení nové verze kódu worker sám o sobě změněné soubory na disku nenačte!
Proto je v deployment skriptu (deploy.sh) nebo při restartu kontejneru nezbytné poslat signál restartu:
php artisan queue:restart
Tento příkaz zapíše do mezipaměti pokyn pro všechny aktivní workery, aby po dokončení právě běžící úlohy korektně ukončili svůj proces. Docker supervisor (nebo orchestrátor) je pak automaticky nastartuje znovu již s novým kódem.
// routes/console.php
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schedule;
Artisan::command('inspire', function (): void {
$this->comment('Anatomie Laravelu 12 & PHP 8.4 — Živá výuková platforma na laravel.heatsharing.cz');
})->purpose('Zobrazí motto výukové platformy');
// Pravidelný noční audit osnovy a souborů kurzu každé ráno ve 3:00
Schedule::command('curriculum:verify')->dailyAt('03:00');
🎯 Ověření znalostí z lekce
Kvíz otestuje pochopení architektury a reálného kódu probíraného v této lekci.
Kde se v Laravelu 12 standardně definují naplánované úlohy (Scheduled Tasks)?
Jaký je rozdíl mezi příkazy schedule:run a schedule:work?
Proč je nutné po nasazení nové verze kódu do produkce provést příkaz php artisan queue:restart?
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | use Illuminate\Support\Facades\Artisan; |
| 6 | use Illuminate\Support\Facades\Schedule; |
| 7 | |
| 8 | Artisan::command('inspire', function (): void { |
| 9 | $this->comment('Anatomie Laravelu 12 & PHP 8.4 — Živá výuková platforma na laravel.heatsharing.cz'); |
| 10 | })->purpose('Zobrazí motto výukové platformy'); |
| 11 | |
| 12 | Schedule::command('curriculum:verify')->dailyAt('03:00'); |
| 13 | |