İçeriğe geç
Muhammet Şafak
en

Laravel Queue ve Supervisor ile Asenkron İşlemler

Laravel'de Queue ve Supervisor ile asenkron iş kuyruğu kurulumu ve arka plan işlemleri.

Kapak görseli — sunucu odasındaki kavisli ekranda [program:laravel-worker] yapılandırması, systemctl status supervisor çıktısı, üç queue:work süreci ve ProcessOrder günlükleri

Bir web isteğinin tek bir görevi vardır: kullanıcıya hızlı yanıt dönmek. Ama bazı işler hızlı değildir — e-posta göndermek, bir görseli işlemek, üçüncü parti bir API’yi beklemek. Bu işleri istek-yanıt döngüsünün içinde yaparsanız, kullanıcı sizin yavaş işinizi bekler. Laravel Queue tam burada devreye giriyor: işi şimdi sıraya koy, yanıtı hemen dön, asıl işi arka planda yap.

Bu yazıda Laravel’de bir iş kuyruğunu nasıl kurduğumu ve onu production’da ayakta tutmak için Supervisor’ı nasıl kullandığımı anlatıyorum.

Kuyruk sürücüsü seçimi

Laravel Queue; veritabanı, Redis, Amazon SQS gibi farklı sürücülerle çalışır. Sürücü, sıraya alınan işlerin nerede saklanacağını belirler. .env dosyasındaki QUEUE_CONNECTION değeri bunu kontrol eder ve Laravel 10.x Queue dokümanının belirttiği gibi yeni uygulamalarda varsayılan sürücü sync’tir — yani iş hiç sıraya alınmaz, anında çalışır. Geliştirme sırasında pratiktir; ama production’da gerçek bir sürücüye geçmeden Queue’nun hiçbir faydasını görmezsiniz.

Bu yazıda veritabanı sürücüsünü kullanıyorum. Küçük ve orta yükte yeterli, ek bir altyapı gerektirmiyor. İşler jobs tablosunda saklanır; dokümanın tarif ettiği gibi tabloyu oluşturmak için:

php artisan queue:table
php artisan migrate

Bir iş tanımlamak

Kuyruğa atılacak her iş bir sınıftır. Örnek olarak arka planda e-posta gönderen bir SendMailJob oluşturuyorum:

php artisan make:job SendMailJob

Üretilen sınıfı, alacağı parametreleri ve yapacağı işi netleştirerek dolduruyorum:

<?php
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

    public function __construct(
        private string $name,
        private string $mail,
    ) {}

    public function handle(): void
    {
        $subject = 'Merhaba ' . $this->name;
        $msg = 'Sitemize üye olduğunuz için teşekkür ederiz!';
        if (!mail($this->mail, $subject, $msg)) {
            throw new \Exception('Mail gönderilemedi.');
        }
    }
}

İki nokta önemli. Birincisi: __construct ile aldığım veriyi sınıfın özelliklerinde saklıyorum — Laravel bu veriyi serialize edip kuyrukta tutuyor, iş çalışınca geri yüklüyor. Bu yüzden constructor’a koca nesneler değil, sade değerler (id’ler, kısa string’ler) vermek iyi bir alışkanlıktır. İkincisi: handle içinde işin başarısız olduğu durumda bir exception fırlatıyorum. Bu isteğe bağlı değil. Doküman şöyle diyor: iş işlenirken bir exception fırlarsa, iş otomatik olarak kuyruğa geri bırakılır ve izin verilen deneme sayısına ulaşana kadar tekrar denenir. İşi kuyruğa elle geri bırakmanın bir yolu daha var — release() — ama sessizce return eden bir job ikisini de yapmaz: kuyruk onu bitmiş kabul eder, başarısız olduğunda bile başarılı sayılır.

İşi kuyruğa atmak tek satır:

\App\Jobs\SendMailJob::dispatch('Muhammet', 'info@muhammetsafak.com.tr');

İşleri yürütmek

Kuyruğa atılan işler kendiliğinden çalışmaz; onları işleyen bir worker gerekir:

php artisan queue:work

Bu komut kuyruğu sürekli dinler ve yeni iş geldikçe işler. Farklı öncelikteki işleri ayırmak isterseniz onQueue() ile adlandırılmış kuyruklar kullanabilir, worker’ı da o kuyruğa yönlendirebilirsiniz:

\App\Jobs\SendMailJob::dispatch($name, $mail)->onQueue('medium');
php artisan queue:work --queue=high,medium,default

Buradaki sıralama önceliği belirler: doküman bunu açıkça söylüyorhigh kuyruğundaki işlerin tamamı işlenmeden medium’a geçilmez.

Supervisor: worker’ı ayakta tutmak

queue:work uzun ömürlü bir süreçtir — ve uzun ömürlü süreçler ölür. Bir hata, bir bellek sınırı, bir deploy… worker durur ve kimse fark etmezse kuyruk sessizce birikir. Production’da bu kabul edilemez.

Supervisor, Unix sistemlerde arka plan süreçlerini izleyen ve durduklarında onları yeniden başlatan bir araçtır. Laravel worker’ları için tam da bunu istiyorum.

sudo apt-get update
sudo apt-get install supervisor -y

/etc/supervisor/conf.d/ altına bir yapılandırma dosyası açıyorum:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /proje/yolu/artisan queue:work --queue=default --tries=3
autostart=true
autorestart=true
user=deploy
numprocs=8
redirect_stderr=true
stdout_logfile=/proje/yolu/storage/logs/worker.log
stopwaitsecs=3600

Birkaç satır kritik. autorestart=true, worker öldüğünde onu geri getirir. numprocs=8 sekiz paralel worker çalıştırır — bu sayıyı yükünüze göre ayarlayın. stopwaitsecs=3600, deploy sırasında çalışan bir işin yarıda kesilmemesi için ona bitmesi adına süre tanır: Supervisor dokümanına göre bu değer, sürece durdurma sinyali gönderildikten sonra kapanmasını beklemek için tanınan saniye sayısıdır ve varsayılanı 10’dur — bir saatlik bir işi on saniyede öldürürsünüz. Laravel’in kendi örnek yapılandırması da aynı sebeple 3600 kullanıyor. Yapılandırmayı tanıtıp başlatmak için:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

Son bir not

Kod değiştirip deploy ettiğinizde, çalışan worker’lar eski kodu bellekte tutmaya devam eder. Doküman bunu ayrı bir başlık altında uyarıyor: worker’lar uzun ömürlü süreçler olduğu için yeniden başlatılmadıkça kodunuzdaki değişiklikleri fark etmezler. Her deploy’dan sonra php artisan queue:restart çalıştırmayı dağıtım adımlarınıza ekleyin — yoksa “kodu güncelledim ama hâlâ eski davranıyor” diye saatlerce uğraşırsınız. Bunu birkaç kez yaşadıktan sonra öğrendim.

Laravel Queue ve Supervisor birlikte, basit ama sağlam bir asenkron işleme katmanı veriyor: Laravel işi tanımlar ve sıraya koyar, Supervisor da o işi yapan süreçlerin hiç durmamasını sağlar. İkisi de tek başına eksik; değer, birlikte çalışmalarında.


Kaynaklar

Bu konuda sorulanlar

Bu konudaki deneyler

Üretim veritabanına giden ad-hoc SQL'i onaya, maskelemeye ve değiştirilemez bir ize bağlayan self-hosted portal; QueryProxy ürününe dönüştü.

Şu an ne yapıyor

Geliştiricinin yazdığı SQL'i üretim veritabanında doğrudan değil, bir onaydan geçirerek çalıştırıyor; sonuçlar diske yazılırken maskeleniyor ve her istek değiştirilemez bir kayda düşüyor. Prod erişimi tek kişide toplanmış ekipler kurabilir.

Açık kaynak Web uygulaması PHP Laravel Livewire +5 daha
Eylül 2026 — Eylül 2026

Ücretsiz ve herkese açık, metin merkezli öğrenme platformu; ders kitabı teorisiyle sektörde karşılaşılan problemleri tek ders akışında tutuyor.

Şu an ne yapıyor

Ücretsiz ve kayıt duvarı olmayan bir öğrenme platformu olarak yayında: alan-müfredat-kurs-ünite-ders hiyerarşisi, tam metin arama, ilerleme takibi ve doğrulanabilir sertifika çalışıyor. Bilgisayar bilimleri müfredatını okumak isteyen herkes bugün kullanabilir.

Web uygulaması Laravel PHP Livewire +6 daha
Ağustos 2026 — Devam ediyor
Etiketler: #PHP#Laravel
Uzmanlık: PHP Geliştirici
Paylaş:

Son güncelleme:

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi