Laravel Task Scheduling & Cronjob-Optimierung für Production
Laravel bietet mit seinem Task Scheduling System eine elegante Alternative zu traditionellen Cron-Einträgen. Statt dutzende Cronjobs direkt auf dem Server zu konfigurieren, definierst du alle wiederkehrenden Aufgaben zentral in deiner Laravel-Anwendung. In diesem Artikel zeige ich dir, wie du Laravel Task Scheduling Cronjob richtig aufsetzt, für Production optimierst und typische Fallstricke vermeidest.
Warum Laravel Task Scheduling nutzen?
Traditionelle Cronjobs erfordern Shell-Zugriff und manuelle Konfiguration auf jedem Server. Laravel Task Scheduling zentralisiert diese Logik in deinem Code:
- Ein einziger Cron-Eintrag statt mehrerer
- Versionskontrolle für deine Scheduling-Logik
- Testbarkeit deiner geplanten Tasks
- Flüssige API für komplexe Zeitpläne
// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->command('emails:send-newsletter')
->weekly()
->mondays()
->at('09:00')
->timezone('Europe/Berlin');
$schedule->command('reports:generate')
->dailyAt('23:30')
->withoutOverlapping();
}
Setup: Der eine Cronjob
Für Laravel Task Scheduling Cronjob brauchst du genau einen Cron-Eintrag auf deinem Server:
* * * * * cd /pfad/zu/deiner/app && php artisan schedule:run >> /dev/null 2>&1
Dieser läuft jede Minute und prüft, welche Tasks fällig sind. Laravel selbst entscheidet intern, was wann ausgeführt wird.
Crontab bearbeiten
# Als Webserver-User (z.B. www-data)
sudo crontab -u www-data -e
# Eintrag hinzufügen
* * * * * cd /var/www/html/deine-app && php artisan schedule:run >> /dev/null 2>&1
Wichtig: Der Cron muss als User laufen, der Schreibrechte auf storage/ und bootstrap/cache/ hat.
Task Definition: Die wichtigsten Patterns
Command Scheduling
Am saubersten: Eigene Artisan Commands für Tasks erstellen.
// app/Console/Commands/CleanupOldRecords.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class CleanupOldRecords extends Command
{
protected $signature = 'cleanup:old-records {--days=30}';
protected $description = 'Löscht Datensätze älter als X Tage';
public function handle()
{
$days = $this->option('days');
$deleted = DB::table('logs')
->where('created_at', '<', now()->subDays($days))
->delete();
$this->info("$deleted Einträge gelöscht");
return 0;
}
}
// app/Console/Kernel.php
$schedule->command('cleanup:old-records --days=60')
->daily()
->at('02:00');
Closure-basierte Tasks
Für einfache Operationen:
$schedule->call(function () {
Cache::put('last-schedule-run', now());
})->everyMinute();
Job Dispatching
Für umfangreiche Background-Prozesse:
$schedule->job(new ProcessReportData)
->dailyAt('01:00')
->onOneServer();
Production-Optimierung für Laravel Task Scheduling
1. Overlapping Prevention
Verhindere, dass ein Task startet, während die vorherige Instanz noch läuft:
$schedule->command('import:heavy-data')
->hourly()
->withoutOverlapping(10); // Timeout nach 10 Minuten
Laravel nutzt Cache als Lock-Mechanism. Stelle sicher, dass dein Cache Driver persistent ist (Redis/Database, nicht Array).
2. Single Server Execution
In Multi-Server-Setups (Load Balancer) muss ein Task nur einmal laufen:
$schedule->command('reports:send')
->daily()
->onOneServer();
Voraussetzung: Zentraler Cache (Redis) oder Database Cache-Driver, den alle Server teilen.
3. Maintenance Mode Handling
$schedule->command('emails:send')
->everyFiveMinutes()
->evenInMaintenanceMode();
Standardmäßig laufen Tasks nicht während php artisan down. Nur für kritische Tasks aktivieren.
4. Fehlerbehandlung & Monitoring
$schedule->command('api:sync')
->everyTenMinutes()
->before(function () {
Log::info('API Sync startet');
})
->after(function () {
Log::info('API Sync abgeschlossen');
})
->onFailure(function () {
// Benachrichtigung senden
Mail::to('admin@example.com')
->send(new TaskFailedMail('api:sync'));
})
->emailOutputOnFailure('dev@example.com');
5. Task Timeouts
Lange laufende Tasks sollten Timeouts haben:
$schedule->command('import:large-dataset')
->daily()
->withoutOverlapping()
->runInBackground() // Blockiert schedule:run nicht
->timeout(3600); // 1 Stunde
Output & Logging
Log in Datei schreiben
$schedule->command('backup:run')
->daily()
->appendOutputTo(storage_path('logs/backup.log'));
Nur bei Output benachrichtigen
$schedule->command('monitor:check')
->everyMinute()
->emailOutputTo('alerts@example.com');
Performance-Tipps für Laravel Task Scheduling Cronjob
Queue Tasks statt direkter Ausführung
Schwere Operationen sollten in Queues:
$schedule->call(function () {
// Schnell: Job nur dispatchen
ProcessMonthlyReports::dispatch();
})->monthly();
Der Scheduler dispatcht nur, der Queue Worker verarbeitet asynchron.
Schedule:work für Development
In Development-Umgebungen ist schedule:work praktischer als Cron:
php artisan schedule:work
Läuft im Vordergrund und führt Tasks kontinuierlich aus – ideal für lokales Testing.
Task-Frequency prüfen
php artisan schedule:list
Zeigt alle Tasks mit nächster Laufzeit. Perfekt zum Verifizieren deiner Konfiguration.
Monitoring & Debugging
Task History tracken
Nutze Packages wie spatie/laravel-schedule-monitor:
composer require spatie/laravel-schedule-monitor
php artisan schedule-monitor:list
Tracked:
- Welche Tasks wann liefen
- Fehlgeschlagene Executions
- Vergessene/nie laufende Tasks
Health Checks mit Timestamps
Einfacher Ansatz ohne Package:
// In Kernel.php
$schedule->call(function () {
Cache::put('scheduler-last-run', now());
})->everyMinute();
// In Health Check
public function checkScheduler()
{
$lastRun = Cache::get('scheduler-last-run');
if (!$lastRun || $lastRun->diffInMinutes(now()) > 5) {
// Alert: Scheduler läuft nicht!
}
}
Typische Probleme & Lösungen
Task läuft nicht
Checklist:
- Cron-Eintrag korrekt?
crontab -lprüfen - PHP-Pfad korrekt?
which phpim Cron verwenden - App-Pfad absolut, nicht relativ
- User-Permissions auf
storage/korrekt?
"No scheduled commands are ready to run"
Normal! Laravel Task Scheduling Cronjob prüft jede Minute, aber führt nur aus, was fällig ist.
Tasks laufen mehrfach (Multi-Server)
onOneServer() verwenden und sicherstellen, dass alle Server denselben Cache nutzen:
// config/cache.php
'default' => env('CACHE_DRIVER', 'redis'),
Timezone-Handling
// In Kernel.php
protected function schedule(Schedule $schedule)
{
// Global
$schedule->useTimezone('Europe/Berlin');
// Oder per Task
$schedule->command('report:daily')
->dailyAt('08:00')
->timezone('America/New_York');
}
Fazit
Laravel Task Scheduling Cronjob ist ein mächtiges Tool für Production-Anwendungen. Mit einem einzigen Cron-Eintrag, sauberer Fehlerbehandlung und richtigen Performance-Optimierungen läuft dein Scheduling System zuverlässig und wartbar.
Die wichtigsten Takeaways:
- Ein Cron-Eintrag für alle Tasks
withoutOverlapping()undonOneServer()für Production- Monitoring über Timestamps oder dedizierte Packages
- Queue Jobs für schwere Operationen
- Zentraler Cache (Redis) in Multi-Server-Setups
Du arbeitest an einem Laravel-Projekt mit komplexen Background-Prozessen oder Scheduling-Anforderungen? Ich helfe dir gerne bei Setup, Optimierung und Production-Deployment deiner Laravel-Anwendung.