Laravel Zamanlanmış Görevler Rehberi

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şti...

Laravel Zamanlanmış Görevler Rehberi

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.php içindeki schedule metodu) 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ün schedule tanı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:run tetiklenmezse hiçbir görev çalışmaz.
  • Yanlış zaman dilimi. Laravel varsayılan olarak config/app.php içindeki timezone ayarını kullanır. Sunucu saatiyle uygulama saat dilimi farklıysa görevler beklediğiniz saatte çalışmaz. Gerekirse görev bazında timezone('Europe/Istanbul') ile açıkça belirtin.
  • Çakışan uzun görevler. withoutOverlapping kullanılmadığında kaynak tüketen görevler üst üste binebilir.
  • Çoklu sunucuda mükerrer çalışma. Yatay ölçeklenen kurulumlarda onOneServer olmadan aynı görev her sunucuda tetiklenir.
  • Kilit süresini yanlış ayarlamak. withoutOverlapping iç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ı. onOneServer ve withoutOverlapping paylaşı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ış

  1. Görevleri schedule metodu içinde tanımlayın.
  2. Uzun görevlerde withoutOverlapping, çoklu sunucuda onOneServer kullanın.
  3. Sunucuya her dakika çalışan schedule:run cron girdisini ekleyin.
  4. Saat dilimi ve kilit sürücüsü ayarlarını doğrulayın.
  5. schedule:list ile 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.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz