Laravel Schedule Kurulumu: Cron, Kilit ve İzleme Rehberi
Laravel Schedule, uygulamanın periyodik işlerini tek bir cron girdisi üzerinden yönetir. Rapor üretme, geçici kayıtları temizleme, ödeme durumlarını kontrol etme veya belirli aralıklarla queue job başlatma gibi görevler kod deposunda görünür hâle gelir. Sağlam bir kurulum için yalnızca daily() yazmak yetmez; cron, zaman dilimi, çakışma kilidi, çoklu sunucu davranışı, çıktı ve hata izleme birlikte düşünülmelidir.
Bu rehberde scheduler tanımı, sunucu cron ayarı, withoutOverlapping, onOneServer, loglama ve test akışını ele alacağız. Sözdizimi sürüme göre değişebileceği için uygulamanızın sürümüne ait resmî Laravel Task Scheduling belgesini temel alın.
Laravel Schedule nasıl çalışır?
Sunucudaki cron her dakika php artisan schedule:run komutunu çağırır. Laravel o anda çalışması gereken görevleri uygulama içindeki tanımlardan seçer. Böylece her iş için ayrı cron satırı oluşturmak yerine görev sıklıkları ve koşulları kaynak kodda tutulur.

Güncel Laravel uygulamalarında görevler çoğunlukla routes/console.php içinde tanımlanır. Bazı proje sürümlerinde app/Console/Kernel.php veya bootstrap/app.php üzerinden yapılandırma görülebilir. Çalışan projenin sürüm yapısını kontrol etmeden dosyaları taşımayın.
use Illuminate\Support\Facades\Schedule;
Schedule::command('reports:daily')
->dailyAt('02:00')
->withoutOverlapping()
->onOneServer();
Görev listesini doğrulama
Tanımların Laravel tarafından görüldüğünü ve sonraki çalışma zamanını kontrol etmek için şu komutu kullanın:
php artisan schedule:list
Görev listede yoksa önce schedule tanımının yüklenen dosyada olduğundan, sınıf adının doğru olduğundan ve uygulamanın boot sırasında hata vermediğinden emin olun. Cache sorunları yaşıyorsanız rastgele dosya silmek yerine uygulama logunu ve ilgili Artisan komutlarının çıktısını inceleyin.
Artisan command, job veya closure seçimi
İş mantığını doğrudan uzun bir schedule closure içine koymak test edilebilirliği azaltır. Tekrar kullanılabilir ve bağımsız bir işlem için Artisan command; asenkron ve yeniden denenebilir iş için queue job; birkaç satırlık yan etkisiz kontrol için closure uygundur.
use App\Jobs\GenerateDailyReport;
use Illuminate\Support\Facades\Schedule;
Schedule::job(new GenerateDailyReport)
->dailyAt('02:00')
->withoutOverlapping();
Scheduler’ın job’ı kuyruğa eklemesi, worker’ın job’ı işlediği anlamına gelmez. Queue connection, worker ve başarısız iş tablosu ayrıca izlenmelidir. Bu katman için Laravel Queue sistemi rehberini kullanın.
Sunucuda cron nasıl eklenir?

Linux sunucuda temel cron girdisi aşağıdaki mantıktadır:
* * * * * cd /var/www/example.com && php artisan schedule:run >> /dev/null 2>&1
Proje yolu ve PHP binary’si sunucunuza göre farklı olabilir. Paylaşımlı hosting panelinde tam PHP yolunu kullanmanız gerekebilir. İlk kurulumda tüm çıktıyı /dev/null adresine atmak yerine geçici bir log dosyasına yönlendirerek komutun gerçekten çalıştığını doğrulayın. Parola, token veya kişisel veri içerebilecek çıktıları web kökünde saklamayın.
cPanel üzerinde proje ve cron yapısını düzenlerken Laravel projesini cPanel’e yükleme rehberi, dağıtım adımları için GitHub Actions ile Laravel deploy rehberi bağlamsal tamamlayıcıdır.
Yerel geliştirmede scheduler çalıştırma
Geliştirme ortamında dakika başı sistem cron tanımlamak yerine Laravel’in desteklediği sürümlerde php artisan schedule:work kullanılabilir. Bu süreç terminal açık kaldığı sürece scheduler’ı önde çalıştırır. Production’da süreç yöneticisi veya standart cron politikası olmadan yalnızca açık bir terminale güvenmeyin.
Görev çakışmasını önleme
Bir görev planlanan aralıktan uzun sürerse yeni örnek önceki bitmeden başlayabilir. Aynı raporu iki kez üretmek, aynı müşteriye tekrar bildirim göndermek veya aynı kayıtları eşzamanlı güncellemek veri tutarsızlığı oluşturabilir. withoutOverlapping() cache tabanlı kilit kullanarak ikinci çalışmayı engeller:
Schedule::command('imports:sync')
->everyFiveMinutes()
->withoutOverlapping(30);
Parametre kilidin dakika cinsinden sona erme süresidir. Görevin normal ve en kötü çalışma süresine göre seçin; çok kısa süre kilit korumasını etkisizleştirebilir, çok uzun süre beklenmeyen kesintiden sonra görevi gereksiz yere durdurabilir. Takılı kalan schedule kilitleri için resmî belgede belirtilen schedule:clear-cache komutunu yalnızca nedenini doğruladıktan sonra kullanın.
Çoklu sunucuda onOneServer kullanımı
Aynı uygulama birden fazla sunucuda ve cron her sunucuda çalışıyorsa görev de her sunucuda tetiklenir. Tek kez yürütülmesi gereken görevlerde onOneServer() kullanın. Bunun çalışması için sunucuların ortak, atomik kilit destekleyen bir cache deposuna bağlanması gerekir.
Schedule::command('billing:close-period')
->monthlyOn(1, '01:00')
->name('billing:close-period')
->onOneServer()
->withoutOverlapping();
Her parametre varyasyonuna benzersiz name() vermek, tek sunucu kilitlerinin birbirini yanlışlıkla paylaşmasını önler. Local dosya cache’i kullanan ayrı sunucular ortak kilit göremez; cache mimarisini production topolojisine göre doğrulayın.
Zaman dilimi ve yaz saati riski
Uygulama zaman dilimi, schedule zaman dilimi ve sunucu sistem saati farklı olabilir. Görev beklenmedik saatte çalışıyorsa üç değeri birlikte kontrol edin. Belirli bölgesel zaman dilimleri yaz saati geçişinde bir saati atlayabilir veya iki kez yaşayabilir; kritik işlemleri mümkünse UTC tabanlı ve idempotent tasarlayın.
“Tam 02:00’de bir kez çalıştı” varsayımı yerine işlenen dönem için benzersiz kayıt veya transaction sınırı kullanın. Seeder ve tekrar çalıştırılabilir veri yaklaşımı için Laravel Seeder ve Factory rehberindeki idempotency mantığı yardımcı olur.
Çıktı, loglama ve hata bildirimi

Komut çıktısı için sürümünüzün desteklediği sendOutputTo, appendOutputTo veya hata/başarı kancaları kullanılabilir. Yalnızca “cron çalıştı” kaydı yeterli değildir. Görev adı, başlangıç zamanı, süre, işlenen kayıt sayısı ve güvenli hata bağlamı izlenmelidir.
Schedule::command('reports:daily')
->dailyAt('02:00')
->before(fn () => logger()->info('Daily report started'))
->onFailure(fn () => logger()->error('Daily report failed'))
->onSuccess(fn () => logger()->info('Daily report completed'));
Loglara erişim tokenı, tam ödeme verisi veya gereksiz kişisel bilgi yazmayın. Hata yönetimi ve güvenli uygulama kontrolleri için Laravel güvenlik kontrol listesini uygulayın.
Schedule görevini test etme
İş mantığını command veya service sınıfında tutarsanız scheduler’dan bağımsız test edebilirsiniz. Schedule tanımının görünür olduğunu schedule:list ile, komut davranışını ise Artisan testiyle doğrulayın:
public function test_daily_report_command_dispatches_job(): void
{
Queue::fake();
$this->artisan('reports:daily')
->assertSuccessful();
Queue::assertPushed(GenerateDailyReport::class);
}
Staging ortamında görevi elle çalıştırırken production verisini etkilemeyecek parametre veya dry-run yolu sağlayın. Test girdilerini tutarlı üretmek için Seeder ve Factory rehberinden yararlanabilirsiniz.
Laravel Schedule kontrol listesi
schedule:listgörevi ve beklenen sonraki zamanı gösteriyor mu?- Sunucu cron’u doğru proje ve PHP yolunu kullanıyor mu?
- Uzun görevlerde
withoutOverlappingve uygun kilit süresi var mı? - Çoklu sunucuda ortak cache ile
onOneServerçalışıyor mu? - Zaman dilimi ve yaz saati etkisi değerlendirildi mi?
- Queue job’ları için worker ve failed job izlemesi mevcut mu?
- Başarı, hata ve çalışma süresi güvenli biçimde loglanıyor mu?
Sıkça Sorulan Sorular
Laravel Schedule için kaç cron girdisi gerekir?
Standart kullanımda sunucuda her dakika schedule:run çağıran tek cron girdisi yeterlidir. Görevlerin sıklığı uygulama kodunda tanımlanır.
Schedule görevi neden çalışmıyor?
Yanlış PHP veya proje yolu, eklenmemiş cron, hatalı zaman dilimi, uygulama boot hatası ya da aktif çakışma kilidi neden olabilir. Önce schedule:list ve manuel schedule:run çıktısını kontrol edin.
withoutOverlapping ne işe yarar?
Önceki görev hâlâ çalışıyorsa aynı görevin yeni örneğinin başlamasını cache kilidiyle engeller. Cache sürücüsü ve kilit süresi doğru yapılandırılmalıdır.
onOneServer ne zaman kullanılır?
Scheduler birden fazla sunucuda çalışıyor ve görevin yalnızca bir kez yürütülmesi gerekiyorsa kullanılır. Tüm sunucular ortak ve atomik kilit destekleyen cache deposuna erişmelidir.
Laravel Schedule ile Queue aynı şey mi?
Hayır. Schedule işin ne zaman başlatılacağını belirler; Queue ise işi asenkron olarak worker’a taşır ve yeniden deneme gibi yürütme davranışlarını yönetir.
Sonuç
Sağlam Laravel Schedule kurulumu; tek cron girdisi, kaynak kodda açık görev tanımları, çakışma ve çoklu sunucu kilitleri, zaman dilimi kararı, güvenli loglama ve testlerden oluşur. Görevleri küçük command veya job sınıflarına ayırın, kritik işlemleri idempotent tasarlayın ve “cron var” bilgisini yeterli kanıt saymayıp gerçek çalışma sonucunu izleyin.




