Laravel Job Sistemi
3 min readNov 5, 2024
Laravel Job sistemini detaylıca inceleyelim:
1. Job Nedir?
- Job’lar uzun süren işlemleri arka planda çalıştırmak için kullanılan sınıflardır
- Queue (kuyruk) sistemi üzerinde çalışırlar
- Kullanıcı deneyimini etkilemeden ağır işlemleri gerçekleştirirler
2. Ne Zaman Kullanılır?
Örnek senaryolar:
- Büyük dosya işlemleri (video/resim işleme)
- Toplu email gönderimi
- Rapor oluşturma
- Veritabanı bakım işlemleri
- API entegrasyonları
- Büyük veri importları
3. Job Sistemi Bileşenleri:
a) Job Sınıfı:
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $podcast;
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
public function handle()
{
// İş mantığı buraya yazılır
}
}
b) Queue Konfigürasyonu:
// config/queue.php
return [
'default' => env('QUEUE_CONNECTION', 'redis'),
'connections' => [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'retry_after' => 90,
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
]
];
4. Job Türleri:
a) Sync Jobs (Senkron):
// Hemen çalıştırılan joblar
class ProcessPodcast
{
public function handle()
{
// Anında işlenir
}
}
b) Queued Jobs (Asenkron):
class ProcessPodcast implements ShouldQueue
{
public $tries = 3; // Deneme sayısı
public $timeout = 120; // Zaman aşımı (saniye)
public $retryAfter = 60; // Tekrar deneme süresi
public $backoff = [60, 120, 180]; // Artan bekleme süreleri
}
5. Job Kullanım Örnekleri:
a) Job Oluşturma:
php artisan make:job ProcessPodcast
b) Job Dispatch Etme Yöntemleri:
// 1. Dispatch helper kullanarak
dispatch(new ProcessPodcast($podcast));
// 2. Dispatchable trait kullanarak
ProcessPodcast::dispatch($podcast);
// 3. Gecikmeli dispatch
ProcessPodcast::dispatch($podcast)->delay(now()->addMinutes(10));
// 4. Belirli bir kuyruğa dispatch
ProcessPodcast::dispatch($podcast)->onQueue('podcasts');
// 5. Zincirlenmiş joblar
ProcessPodcast::withChain([
new OptimizePodcast($podcast),
new ReleasePodcast($podcast)
])->dispatch();
6. Detaylı Bir Job Örneği:
class ProcessVideoUpload implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $video;
public $tries = 3;
public $timeout = 300;
public function __construct(Video $video)
{
$this->video = $video;
}
public function handle(VideoProcessor $processor)
{
try {
// Video işleme
$processor->process($this->video);
// Thumbnail oluşturma
$processor->createThumbnail($this->video);
// Video durumunu güncelleme
$this->video->update(['status' => 'processed']);
} catch (Exception $e) {
$this->fail($e);
}
}
public function failed($exception)
{
// Hata durumunda yapılacaklar
Log::error('Video processing failed', [
'video' => $this->video->id,
'error' => $exception->getMessage()
]);
// Kullanıcıya bildirim gönderme
$this->video->user->notify(new VideoProcessingFailed($this->video));
}
}
7. Queue Worker Yönetimi:
a) Worker Başlatma:
# Temel worker başlatma
php artisan queue:work
# Belirli bir connection için worker
php artisan queue:work redis
# Belirli bir queue için worker
php artisan queue:work redis --queue=high,default
# Supervisor ile worker yönetimi
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=8
redirect_stderr=true
8. Job Özellikleri ve Middleware:
a) Unique Jobs:
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function middleware()
{
return [new WithoutOverlapping($this->podcast->id)];
}
}
b) Rate Limiting:
use Illuminate\Queue\Middleware\RateLimited;
public function middleware()
{
return [new RateLimited('podcasts')];
}
9. Job Events ve Monitoring:
// Queue Events dinleme
Queue::before(function (JobProcessing $event) {
// Job başlamadan önce
});
Queue::after(function (JobProcessed $event) {
// Job tamamlandıktan sonra
});
Queue::failing(function (JobFailed $event) {
// Job hata aldığında
});
// Horizon ile monitoring (Redis queue için)
composer require laravel/horizon
php artisan horizon:install
10. Best Practices:
Job Boyutu:
- Job sınıfları küçük ve odaklı olmalı
- Tek bir sorumluluğa sahip olmalı
Error Handling:
public function handle()
{
try {
// İş mantığı
} catch (Exception $e) {
$this->fail($e);
// veya yeniden deneme
$this->release(30); // 30 saniye sonra tekrar dene
}
}
Queue Önceliklendirme:
// Farklı öncelikli kuyruklar
'queue' => 'high,default,low'
// Job'ı yüksek öncelikli kuyruğa gönderme
ProcessPodcast::dispatch($podcast)->onQueue('high');
Job Data Serialization:
// Sadece gerekli dataları serialize etme
public function __sleep()
{
return ['podcast_id'];
}
Testing:
class ProcessPodcastTest extends TestCase
{
public function test_podcast_can_be_processed()
{
Queue::fake();
// Job'ı dispatch et
ProcessPodcast::dispatch($podcast);
// Job'ın dispatch edildiğini doğrula
Queue::assertPushed(ProcessPodcast::class, function ($job) use ($podcast) {
return $job->podcast->id === $podcast->id;
});
}
}