Laravel'in zamanlanmış görev altyapısı, sunucuda tek bir cron girdisiyle birden fazla periyodik işi yönetmenizi sağlar. Bu rehber, orta seviye geliştiriciler için görevlerin tanımlanması, çalıştırılması ve izlenmesi adımlarını kapsar.
Önkoşullar ve Kapsam
- Çalışan bir Laravel uygulaması ve komut satırına erişim.
- Sunucuda cron servisinin kurulu ve çalışır durumda olması.
- Laravel'in zamanlayıcı API'si (
app/Console/Kernel.phpiçindekischedulemetodu) sürümler arasında büyük ölçüde sabit kalmıştır. Laravel 10 ve sonrasında iskelet yapısı değişmiş olsa da kavramlar aynıdır. Bu rehber belirli bir sürüm numarası varsaymaz; kullandığınız sürümünscheduletanımını nereye koyduğunu resmi dokümantasyondan doğrulayın.
Zamanlayıcı Nasıl Çalışır
Laravel'in zamanlayıcısı, sistem cron'una her dakika tetiklenen tek bir girdi eklemenizi bekler. Bu girdi schedule:run Artisan komutunu çağırır. Laravel her çalıştırmada tanımlı görevleri kontrol eder ve o dakikada çalışması gerekenleri yürütür. Yani görev sıklığını cron ifadeleriyle değil, uygulama içindeki tanımlarla yönetirsiniz.
Sunucudaki cron girdisi tipik olarak şu biçimdedir:
* * * * * cd /proje/yolu && php artisan schedule:run >> /dev/null 2>&1
Bu satır her dakika çalışır; asıl zamanlama mantığı uygulamanın içindedir.
Görev Tanımlama
Görevler schedule metodu içinde tanımlanır. Bir closure, bir Artisan komutu veya çağrılabilir bir sınıf zamanlanabilir.
use App\Console\Commands\TemizlikYap;
use Illuminate\Support\Facades\Schedule;
Schedule::command('temizlik:yap')->daily();
Schedule::call(function () {
// periyodik iş
})->hourly();
Sıklık metotları okunabilirlik için zincirlenir: everyMinute, hourly, daily, weekly, monthly gibi. Daha ince ayar için cron('0 3 * * *') ile doğrudan cron ifadesi de verebilirsiniz.
Çakışmayı Önleme
Uzun süren bir görev, bir sonraki tetiklenmeyle üst üste binebilir. Bunu engellemek için:
Schedule::command('rapor:olustur')->hourly()->withoutOverlapping();
withoutOverlapping, görev hâlâ çalışırken yeni bir örneğin başlamasını engeller. Varsayılan kilit süresi 24 saattir; withoutOverlapping(10) gibi bir dakika değeri vererek bunu daraltabilirsiniz.
Tek Sunucuda Çalıştırma
Birden fazla uygulama sunucunuz varsa ve görevin yalnızca birinde çalışması gerekiyorsa:
Schedule::command('fatura:kes')->daily()->onOneServer();
onOneServer, görevi atomik bir kilit üzerinden tek sunucuya bağlar. Bu özelliğin çalışması için görevlerin adlandırılmış olması ve paylaşılan bir önbellek sürücüsünün (örneğin Redis veya veritabanı) yapılandırılmış olması gerekir.
Görevleri Elle Çalıştırma ve İzleme
Geliştirme sırasında schedule:run komutunu elle çalıştırarak o dakikada hangi görevlerin tetiklendiğini görebilirsiniz. Tanımlı tüm görevlerin listesini ve bir sonraki çalışma zamanlarını görmek için:
php artisan schedule:list
Üretimde görev çıktısını kaydetmek isterseniz, görev tanımına appendOutputTo veya emailOutputTo gibi metotlar ekleyebilirsiniz. Bu, sessiz başarısızlıkları fark etmeyi kolaylaştırır.
Yaygın Hatalar
- Cron girdisini eklemeyi unutmak. Uygulama içinde tanım yapmak tek başına yeterli değildir; sunucuda
schedule:runtetiklenmezse hiçbir görev çalışmaz. - Yanlış zaman dilimi. Laravel varsayılan olarak
config/app.phpiçindekitimezoneayarını kullanır. Sunucu saatiyle uygulama saat dilimi farklıysa görevler beklediğiniz saatte çalışmaz. Gerekirse görev bazındatimezone('Europe/Istanbul')ile açıkça belirtin. - Çakışan uzun görevler.
withoutOverlappingkullanılmadığında kaynak tüketen görevler üst üste binebilir. - Çoklu sunucuda mükerrer çalışma. Yatay ölçeklenen kurulumlarda
onOneServerolmadan aynı görev her sunucuda tetiklenir. - Kilit süresini yanlış ayarlamak.
withoutOverlappingiçin çok kısa bir süre vermek, görev bitmeden kilidin açılmasına ve çakışmaya yol açabilir.
Güvenlik Etkileri
- Komut enjeksiyonu. Zamanlanan görevlere dışarıdan gelen veriyi (kullanıcı girdisi, sorgu parametresi) doğrudan komut argümanı olarak geçirmeyin. Kullanıcı kontrollü değerler komut satırına sızarsa kötü niyetli komutlar çalıştırılabilir.
- Çıktı sızıntısı. Görev çıktısını dosyaya veya e-postaya yönlendirirken hassas veri (token, kimlik bilgisi, kişisel veri) içermediğinden emin olun; log ve posta kutuları erişilebilir olabilir.
- Kilit altyapısı.
onOneServervewithoutOverlappingpaylaşılan bir önbellek kullanır. Bu sürücünün yetkisiz erişime kapalı olduğundan emin olun; aksi halde kilitler manipüle edilebilir. - Cron çalıştırma kullanıcısı. Cron girdisini uygulama dosyalarına erişimi olan, ancak gereksiz geniş yetkileri bulunmayan bir kullanıcı altında tanımlayın.
Özet Akış
- Görevleri
schedulemetodu içinde tanımlayın. - Uzun görevlerde
withoutOverlapping, çoklu sunucudaonOneServerkullanın. - Sunucuya her dakika çalışan
schedule:runcron girdisini ekleyin. - Saat dilimi ve kilit sürücüsü ayarlarını doğrulayın.
schedule:listile tanımları, çıktı kaydı ile de çalışma sonuçlarını izleyin.
Bu adımlar, Laravel sürümünden bağımsız olarak zamanlanmış görev altyapınızın öngörülebilir ve güvenli çalışmasını sağlar.