aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Web Geliştirme

Laravel Queue ve Job: Arka Plan İşleri Rehberi

Bir Laravel queue, hoş geldin maili göndermek, görsel işlemek ya da bir API'ye istek atmak gibi yavaş işleri istek-yanıt döngüsünden çıkarıp arka plana taşımanızı sağlar. Kullanıcı, e-postanın gerçekten gönderilmesini beklemek zorunda kalmaz; iş bir kuyruğa atılır ve arka planda çalışan bir worker tarafından sırası geldiğinde işlenir. Bu yazıda kuyruk altyapısını sıfırdan kurmayı, kendi job sınıfınızı yazmayı, worker'ı çalıştırmayı ve hataları sağlam biçimde yönetmeyi adım adım göreceğiz.

Neden kuyruğa ihtiyaç duyarsınız?

Senkron çalışan bir uygulamada her şey aynı istek içinde olur. Kullanıcı kayıt formunu gönderir, siz mail atarsınız, belki bir görsel küçültürsünüz ve ancak ondan sonra tarayıcıya yanıt döner. Mail sunucusu yavaşsa kullanıcı saniyelerce bekler. Kuyruk bu işleri ayırır:

  • Hız: Yavaş işler arka plana gider, yanıt anında döner.
  • Dayanıklılık: İş başarısız olursa otomatik olarak yeniden denenebilir.
  • Ölçeklenebilirlik: Birden fazla worker çalıştırıp yükü dağıtabilirsiniz.

Kuyruk sürücüsünü seçmek

Laravel birden çok kuyruk sürücüsü destekler ve hepsi tek bir API'nin arkasında durur. .env dosyanızdaki QUEUE_CONNECTION değişkeniyle seçersiniz:

QUEUE_CONNECTION=database

Yaygın seçenekler şunlardır:

  • sync — varsayılan; iş anında, aynı istekte çalışır. Yerel geliştirme dışında işe yaramaz.
  • database — işleri bir veritabanı tablosunda tutar. Kurulumu kolaydır, küçük/orta projeler için yeterlidir.
  • redis — yüksek hacim için hızlı ve önerilen seçenek.
  • sqs — Amazon SQS ile yönetilen, sunucusuz kuyruk.

database sürücüsünü kullanacaksanız, kuyruk için bir tablo gerekir. Laravel bunu üreten bir komut sunar:

php artisan make:queue-table
php artisan migrate

İlk job sınıfınızı oluşturmak

Bir job, kuyrukta çalışacak tek bir iş birimidir. artisan ile oluşturun:

php artisan make:job SendWelcomeEmail

Bu, app/Jobs/SendWelcomeEmail.php dosyasını üretir. ShouldQueue arayüzünü uygulayan bir sınıf, otomatik olarak kuyruğa alınır. handle() metodu işin gerçek mantığını barındırır:

<?php

namespace App\Jobs;

use App\Models\User;
use App\Mail\WelcomeMail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public User $user) {}

    public function handle(): void
    {
        Mail::to($this->user)->send(new WelcomeMail($this->user));
    }
}

Dikkat edilmesi gereken nokta: yapıcıya bir User modeli veriyoruz. SerializesModels trait'i sayesinde modelin tamamı değil, yalnızca birincil anahtarı serileştirilir; iş çalıştığında model veritabanından taze olarak yeniden yüklenir.

Job'u kuyruğa atmak (dispatch)

Job'u tetiklemek için dispatch kullanılır. En sade hali statik metottur:

use App\Jobs\SendWelcomeEmail;

SendWelcomeEmail::dispatch($user);

Akıcı zincirleme yöntemlerle işin nasıl çalışacağını ayarlayabilirsiniz:

SendWelcomeEmail::dispatch($user)
    ->onQueue('emails')        // belirli bir kuyruğa
    ->delay(now()->addMinutes(5)); // 5 dakika gecikmeli

Birden fazla işi sırayla çalıştırmak için Bus::chain(), paralel gruplar için Bus::batch() kullanabilirsiniz. Küçük başlamak iyidir; bu özelliklere ihtiyaç duydukça eklersiniz.

Worker'ı çalıştırmak

İşler kuyruğa düşer ama onları işleyecek bir sürece ihtiyaç vardır. İşte worker bunun için:

php artisan queue:work

Bu komut sürekli çalışır ve yeni işleri bekler. Önemli birkaç bayrak:

  • --queue=emails,default — kuyrukları öncelik sırasına göre dinler.
  • --tries=3 — bir iş başarısız olursa en fazla kaç kez denensin.
  • --timeout=60 — bir işin en fazla kaç saniye sürebileceği.

Çok önemli bir nokta: queue:work uygulamanızı belleğe yükler. Kodu değiştirdiğinizde worker eski kodu çalıştırmaya devam eder. Bu yüzden her deploy sonrası worker'ı yeniden başlatmanız gerekir:

php artisan queue:restart

Üretim ortamında worker'ın çökse bile yeniden ayağa kalkması için Supervisor gibi bir süreç yöneticisi kullanın. Supervisor, queue:work sürecini izler ve gerektiğinde otomatik yeniden başlatır.

Başarısız işleri yönetmek

İşler bazen başarısız olur: mail sunucusu yanıt vermez, bir API zaman aşımına uğrar. Tüm denemeler tükendiğinde Laravel işi failed_jobs tablosuna kaydeder. Bu tablo için migration'ı oluşturun:

php artisan make:queue-failed-table
php artisan migrate

Başarısız işleri listeleyebilir ve yeniden deneyebilirsiniz:

php artisan queue:failed       # listele
php artisan queue:retry all    # hepsini yeniden dene
php artisan queue:flush        # hepsini sil

Job sınıfınıza bir failed() metodu eklerseniz, iş kalıcı olarak başarısız olduğunda çalışır; burada yöneticiye bildirim atabilir veya log düşebilirsiniz. Ayrıca $backoff özelliğiyle yeniden denemeler arasına bekleme süresi koyabilirsiniz; bu, geçici sorunlarda servisi bunaltmamak için kritiktir.

Sık Sorulan Sorular

database ve redis sürücüsü arasında nasıl seçim yaparım?

Günde birkaç bin işe kadar database gayet yeterlidir ve ek altyapı gerektirmez. Yüksek hacim, düşük gecikme ya da Bus::batch() gibi gelişmiş özellikler kullanacaksanız Redis'e geçin. Çoğu proje database ile başlayıp ihtiyaç doğunca geçiş yapar.

Worker'ı kod değişikliğinden sonra neden yeniden başlatmalıyım?

Çünkü queue:work uzun ömürlü bir süreçtir ve uygulamayı bir kez belleğe yükler. Değiştirdiğiniz kod bellekteki kopyaya yansımaz. php artisan queue:restart mevcut işleri bitirip worker'a güvenli şekilde yeniden başlamasını söyler.

Bir iş ne kadar süre çalışabilir?

--timeout bayrağıyla belirlenir (varsayılan 60 saniye). Daha uzun süren işler için değeri artırın, ama timeout'un işin retry_after ayarından kısa olmasına dikkat edin; aksi halde aynı iş iki kez işlenebilir.

Kuyruğunuz çalışmaya başlasın istiyorsanız projenizdeki yavaş noktaları birlikte bulup arka plana taşıyabiliriz; Laravel altyapınızı kurmak veya optimize etmek için benimle iletişime geçin.

Devamı için